Merge "Revert "Make SubscriptionManager.getSlotIndex public""
diff --git a/Android.bp b/Android.bp
index 6266abe..7e71bdf 100644
--- a/Android.bp
+++ b/Android.bp
@@ -77,6 +77,7 @@
         "core/java/android/app/ISearchManager.aidl",
         "core/java/android/app/ISearchManagerCallback.aidl",
         "core/java/android/app/IServiceConnection.aidl",
+        "core/java/android/app/ISmsAppService.aidl",
         "core/java/android/app/IStopUserCallback.aidl",
         "core/java/android/app/job/IJobCallback.aidl",
         "core/java/android/app/job/IJobScheduler.aidl",
@@ -151,9 +152,10 @@
         ":libcamera_client_framework_aidl",
         "core/java/android/hardware/IConsumerIrService.aidl",
         "core/java/android/hardware/ISerialManager.aidl",
-        "core/java/android/hardware/biometrics/IBiometricPromptService.aidl",
-        "core/java/android/hardware/biometrics/IBiometricPromptServiceReceiver.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/IBiometricServiceLockoutResetCallback.aidl",
         "core/java/android/hardware/display/IDisplayManager.aidl",
         "core/java/android/hardware/display/IDisplayManagerCallback.aidl",
@@ -194,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",
@@ -368,6 +371,7 @@
         "core/java/com/android/internal/app/IAppOpsService.aidl",
         "core/java/com/android/internal/app/IBatteryStats.aidl",
         "core/java/com/android/internal/app/ISoundTriggerService.aidl",
+        "core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl",
         "core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl",
         "core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl",
         "core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.aidl",
@@ -514,11 +518,14 @@
         "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
         "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
+        "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IDownloadStatusListener.aidl",
         "telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl",
         "telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl",
+        "telephony/java/android/telephony/mbms/IGroupCallCallback.aidl",
         "telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl",
         "telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl",
+        "telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl",
         "telephony/java/android/telephony/INetworkService.aidl",
         "telephony/java/android/telephony/INetworkServiceCallback.aidl",
         "telephony/java/com/android/ims/internal/IImsCallSession.aidl",
@@ -555,7 +562,7 @@
         "telephony/java/com/android/internal/telephony/IPhoneSubInfo.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",
@@ -697,12 +704,12 @@
         "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",
     ],
 
     // Loaded with System.loadLibrary by android.view.textclassifier
     required: [
-        "libtextclassifier",
         "libmedia2_jni",
     ],
 
@@ -806,12 +813,16 @@
 java_library {
     name: "ext",
     installable: true,
-    no_framework_libs: true,
+    sdk_version: "core_current",
     static_libs: [
         "libphonenumber-platform",
         "nist-sip",
         "tagsoup",
         "rappor",
+        "libtextclassifier-java",
+    ],
+    required: [
+        "libtextclassifier",
     ],
     dxflags: ["--core-library"],
 }
@@ -1281,6 +1292,9 @@
 }
 
 droiddoc {
+    // Please sync with android-api-council@ before making any changes for the name property below.
+    // Since there's cron jobs that fetch offline-sdk-referenceonly-docs-docs.zip periodically.
+    // See b/116221385 for reference.
     name: "offline-sdk-referenceonly-docs",
     defaults: ["framework-docs-default"],
     srcs: [
@@ -1297,6 +1311,9 @@
 }
 
 droiddoc {
+    // Please sync with android-api-council@ before making any changes for the name property below.
+    // Since there's cron jobs that fetch offline-system-sdk-referenceonly-docs-docs.zip periodically.
+    // See b/116221385 for reference.
     name: "offline-system-sdk-referenceonly-docs",
     defaults: ["framework-docs-default"],
     srcs: [
@@ -1590,6 +1607,7 @@
             removed_api_file: "api/removed.txt",
         },
     },
+    jdiff_enabled: true,
 }
 
 droidstubs {
@@ -1614,6 +1632,7 @@
             removed_api_file: "api/system-removed.txt",
         },
     },
+    jdiff_enabled: true,
 }
 
 droidstubs {
diff --git a/Android.mk b/Android.mk
index 73c0233..d333074 100644
--- a/Android.mk
+++ b/Android.mk
@@ -53,262 +53,10 @@
 	cat $^ | sort -u > $@.tmp
 	$(call commit-change-for-toc,$@)
 
-# the documentation
-# ============================================================
-
-# TODO: deal with com/google/android/googleapps
-packages_to_document := \
-  android \
-  javax/microedition/khronos \
-  org/apache/http/conn \
-  org/apache/http/params \
-
-# include definition of libcore_to_document
-include libcore/Docs.mk
-
-non_base_dirs := \
-  ../opt/telephony/src/java/android/telephony \
-  ../opt/telephony/src/java/android/telephony/gsm \
-  ../opt/net/voip/src/java/android/net/rtp \
-  ../opt/net/voip/src/java/android/net/sip \
-
-# Find all files in specific directories (relative to frameworks/base)
-# to document and check apis
-files_to_check_apis := \
-  $(call find-other-java-files, \
-    $(non_base_dirs) \
-  )
-
-# Find all files in specific packages that were used to compile
-# framework.jar to document and check apis
-files_to_check_apis += \
-  $(addprefix ../../,\
-    $(filter \
-      $(foreach dir,$(FRAMEWORKS_BASE_JAVA_SRC_DIRS),\
-        $(foreach package,$(packages_to_document),\
-          $(dir)/$(package)/%.java)),\
-      $(SOONG_FRAMEWORK_SRCS)))
-
-# Find all generated files that were used to compile framework.jar
-files_to_check_apis_generated := \
-  $(filter $(OUT_DIR)/%,\
-    $(SOONG_FRAMEWORK_SRCS))
-
-# These are relative to frameworks/base
-# FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
-files_to_document := \
-  $(files_to_check_apis) \
-  $(call find-other-java-files,\
-    test-base/src \
-    test-mock/src \
-    test-runner/src)
-
-# These are relative to frameworks/base
-html_dirs := \
-	$(FRAMEWORKS_BASE_SUBDIRS) \
-	$(non_base_dirs) \
-
-# Common sources for doc check and api check
-common_src_files := \
-	$(call find-other-html-files, $(html_dirs)) \
-	$(addprefix ../../, $(libcore_to_document)) \
-
-# These are relative to frameworks/base
-framework_docs_LOCAL_SRC_FILES := \
-  $(files_to_document) \
-  $(common_src_files) \
-
-# These are relative to frameworks/base
-framework_docs_LOCAL_API_CHECK_SRC_FILES := \
-  $(files_to_check_apis) \
-  $(common_src_files) \
-
 # This is used by ide.mk as the list of source files that are
 # always included.
 INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document))
 
-framework_docs_LOCAL_DROIDDOC_SOURCE_PATH := \
-	$(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
-
-framework_docs_LOCAL_SRCJARS := $(SOONG_FRAMEWORK_SRCJARS)
-
-framework_docs_LOCAL_GENERATED_SOURCES := \
-  $(libcore_to_document_generated) \
-  $(files_to_check_apis_generated) \
-
-framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES := \
-	core-oj \
-	core-libart \
-	conscrypt \
-	bouncycastle \
-	okhttp \
-	ext \
-	framework \
-	voip-common \
-
-# Platform docs can refer to Support Library APIs, but we don't actually build
-# them as part of the docs target, so we need to include them on the classpath.
-framework_docs_LOCAL_JAVA_LIBRARIES := \
-	$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES) \
-	$(FRAMEWORKS_SUPPORT_JAVA_LIBRARIES)
-
-framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
-# The since flag (-since N.xml API_LEVEL) is used to add API Level information
-# to the reference documentation. Must be in order of oldest to newest.
-#
-# Conscrypt (com.android.org.conscrypt) is an implementation detail and should
-# not be referenced in the documentation.
-framework_docs_LOCAL_DROIDDOC_OPTIONS := \
-    -android \
-    -knowntags ./frameworks/base/docs/knowntags.txt \
-    -knowntags ./libcore/known_oj_tags.txt \
-    -manifest ./frameworks/base/core/res/AndroidManifest.xml \
-    -hidePackage com.android.internal \
-    -hidePackage com.android.internal.util \
-    -hidePackage com.android.okhttp \
-    -hidePackage com.android.org.conscrypt \
-    -hidePackage com.android.server
-
-# Convert an sdk level to a "since" argument.
-since-arg = -since $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(1)/public/api/android.$(2)) $(1)
-
-finalized_xml_sdks := $(call numerically_sort,\
-    $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.xml,%,\
-    $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.xml)))
-finalized_txt_sdks := $(call numerically_sort,\
-     $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,%,\
-    $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt)))
-
-framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_xml_sdks),$(call since-arg,$(sdk),xml))
-framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_txt_sdks),$(call since-arg,$(sdk),txt))
-ifneq ($(PLATFORM_VERSION_CODENAME),REL)
-  framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-      -since ./frameworks/base/api/current.txt $(PLATFORM_VERSION_CODENAME)
-endif
-framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-    -werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
-    -overview $(LOCAL_PATH)/core/java/overview.html
-
-framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
-	$(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)
-
-framework_docs_LOCAL_ADDITIONAL_JAVA_DIR:= \
-	$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
-
-framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES := \
-    frameworks/base/docs/knowntags.txt \
-    $(libcore_to_document_generated)
-
-samples_dir := development/samples/browseable
-
-# Whitelist of valid groups, used for default TOC grouping. Each sample must
-# belong to one (and only one) group. Assign samples to groups by setting
-# a sample.group var to one of these groups in the sample's _index.jd.
-sample_groups := -samplegroup Admin \
-                 -samplegroup Background \
-                 -samplegroup Connectivity \
-                 -samplegroup Content \
-                 -samplegroup Input \
-                 -samplegroup Media \
-                 -samplegroup Notification \
-                 -samplegroup RenderScript \
-                 -samplegroup Security \
-                 -samplegroup Sensors \
-                 -samplegroup System \
-                 -samplegroup Testing \
-                 -samplegroup UI \
-                 -samplegroup Views \
-                 -samplegroup Wearable
-
-## SDK version identifiers used in the published docs
-  # major[.minor] version for current SDK. (full releases only)
-framework_docs_SDK_VERSION:=7.0
-  # release version (ie "Release x")  (full releases only)
-framework_docs_SDK_REL_ID:=1
-
-framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-		-hdf dac true \
-		-hdf sdk.codename O \
-		-hdf sdk.preview.version 1 \
-		-hdf sdk.version $(framework_docs_SDK_VERSION) \
-		-hdf sdk.rel.id $(framework_docs_SDK_REL_ID) \
-		-hdf sdk.preview 0 \
-		-resourcesdir $(LOCAL_PATH)/docs/html/reference/images/ \
-		-resourcesoutdir reference/android/images/
-
-# Federate Support Library references against local API file.
-framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-		-federate SupportLib https://developer.android.com \
-		-federationapi SupportLib prebuilts/sdk/current/support-api.txt
-
-# Federate AndroidX references against local API file.
-framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-		-federate AndroidX https://developer.android.com \
-		-federationapi AndroidX prebuilts/sdk/current/androidx-api.txt
-
-# Get the highest numbered api txt for the given api level.
-# $(1): the api level (e.g. public, system)
-define highest_sdk_txt
-$(HISTORICAL_SDK_VERSIONS_ROOT)/$(lastword $(call numerically_sort, \
-    $(patsubst \
-        $(HISTORICAL_SDK_VERSIONS_ROOT)/%,\
-        %,\
-        $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/$(1)/api/android.txt)\
-    ) \
-))
-endef
-
-# ====  Public API diff ===========================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(framework_docs_LOCAL_API_CHECK_SRC_FILES)
-LOCAL_GENERATED_SOURCES := $(framework_docs_LOCAL_GENERATED_SOURCES)
-LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
-LOCAL_JAVA_LIBRARIES := $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
-LOCAL_MODULE_CLASS := $(framework_docs_LOCAL_MODULE_CLASS)
-LOCAL_ADDITIONAL_JAVA_DIR := $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-	$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES) \
-	$(INTERNAL_PLATFORM_API_FILE)
-
-LOCAL_MODULE := offline-sdk-referenceonly
-
-# Basename, because apidiff adds .txt internally.
-LOCAL_APIDIFF_OLDAPI := $(basename $(call highest_sdk_txt,public))
-LOCAL_APIDIFF_NEWAPI := $(LOCAL_PATH)/../../$(basename $(INTERNAL_PLATFORM_API_FILE))
-
-include $(BUILD_APIDIFF)
-
-# Hack to get diffs included in docs output
-out_zip := $(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip
-$(out_zip): $(full_target)
-
-# ====  System API diff ===========================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(framework_docs_LOCAL_API_CHECK_SRC_FILES)
-LOCAL_GENERATED_SOURCES := $(framework_docs_LOCAL_GENERATED_SOURCES)
-LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
-LOCAL_JAVA_LIBRARIES := $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
-LOCAL_MODULE_CLASS := $(framework_docs_LOCAL_MODULE_CLASS)
-LOCAL_ADDITIONAL_JAVA_DIR := $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-	$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES) \
-	$(INTERNAL_PLATFORM_SYSTEM_API_FILE)
-
-LOCAL_MODULE := offline-system-sdk-referenceonly
-
-# Basename, because apidiff adds .txt internally.
-LOCAL_APIDIFF_OLDAPI := $(basename $(call highest_sdk_txt,system))
-LOCAL_APIDIFF_NEWAPI := $(LOCAL_PATH)/../../$(basename $(INTERNAL_PLATFORM_SYSTEM_API_FILE))
-
-include $(BUILD_APIDIFF)
-
-# Hack to get diffs included in docs output
-out_zip := $(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip
-$(out_zip): $(full_target)
-
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE))
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE))
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE))
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2247e43..6deda0c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -247,6 +247,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.media.remotedisplay.jar)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index de83f3e..ff40f75 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -8,6 +8,11 @@
                       services/print/
                       services/usb/
                       telephony/
+                      tests/ActivityViewTest/
+                      tests/LotsOfApps/
+                      tests/NativeProcessesMemoryTest/
+                      tests/OdmApps/
+                      tests/SystemMemoryTest/
                       wifi/
 
 api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT}
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/api/current.txt b/api/current.txt
index 75787a7..3a44d34 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -7,6 +7,7 @@
   public static final class Manifest.permission {
     ctor public Manifest.permission();
     field public static final java.lang.String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
+    field public static final java.lang.String ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION";
     field public static final java.lang.String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
     field public static final java.lang.String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
     field public static final java.lang.String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
@@ -22,6 +23,7 @@
     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";
@@ -37,6 +39,7 @@
     field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
     field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
     field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
+    field public static final java.lang.String BIND_SMS_APP_SERVICE = "android.permission.BIND_SMS_APP_SERVICE";
     field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
     field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
     field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
@@ -278,7 +281,7 @@
     field public static final int allowBackup = 16843392; // 0x1010280
     field public static final int allowClearUserData = 16842757; // 0x1010005
     field public static final int allowEmbedded = 16843765; // 0x10103f5
-    field public static final int allowForceDark = 16844171; // 0x101058b
+    field public static final int allowForceDark = 16844172; // 0x101058c
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
     field public static final int allowSingleTap = 16843353; // 0x1010259
     field public static final int allowTaskReparenting = 16843268; // 0x1010204
@@ -772,9 +775,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 = 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 = 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
@@ -934,7 +939,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
@@ -974,10 +979,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
@@ -993,6 +998,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
@@ -1302,7 +1308,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
@@ -4296,6 +4302,20 @@
     method public abstract void onActivityCreated(android.app.Activity, android.os.Bundle);
     method public abstract void onActivityDestroyed(android.app.Activity);
     method public abstract void onActivityPaused(android.app.Activity);
+    method public default void onActivityPostCreated(android.app.Activity, android.os.Bundle);
+    method public default void onActivityPostDestroyed(android.app.Activity);
+    method public default void onActivityPostPaused(android.app.Activity);
+    method public default void onActivityPostResumed(android.app.Activity);
+    method public default void onActivityPostSaveInstanceState(android.app.Activity, android.os.Bundle);
+    method public default void onActivityPostStarted(android.app.Activity);
+    method public default void onActivityPostStopped(android.app.Activity);
+    method public default void onActivityPreCreated(android.app.Activity, android.os.Bundle);
+    method public default void onActivityPreDestroyed(android.app.Activity);
+    method public default void onActivityPrePaused(android.app.Activity);
+    method public default void onActivityPreResumed(android.app.Activity);
+    method public default void onActivityPreSaveInstanceState(android.app.Activity, android.os.Bundle);
+    method public default void onActivityPreStarted(android.app.Activity);
+    method public default void onActivityPreStopped(android.app.Activity);
     method public abstract void onActivityResumed(android.app.Activity);
     method public abstract void onActivitySaveInstanceState(android.app.Activity, android.os.Bundle);
     method public abstract void onActivityStarted(android.app.Activity);
@@ -6095,6 +6115,11 @@
     method public abstract void onSharedElementsReady();
   }
 
+  public class SmsAppService extends android.app.Service {
+    ctor public SmsAppService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+  }
+
   public deprecated class TabActivity extends android.app.ActivityGroup {
     ctor public TabActivity();
     method public android.widget.TabHost getTabHost();
@@ -6712,14 +6737,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
@@ -9527,6 +9559,7 @@
     field public static final int BIND_IMPORTANT = 64; // 0x40
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
+    field public static final java.lang.String BIOMETRIC_SERVICE = "biometric";
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
     field public static final java.lang.String CAMERA_SERVICE = "camera";
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
@@ -9952,7 +9985,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";
@@ -10025,7 +10058,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";
@@ -13229,6 +13262,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
@@ -13373,6 +13407,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);
@@ -13724,6 +13760,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;
@@ -14006,6 +14043,10 @@
     method public float getRunAdvance(char[], int, int, int, int, boolean, int);
     method public float getRunAdvance(java.lang.CharSequence, int, int, int, int, boolean, int);
     method public android.graphics.Shader getShader();
+    method public int getShadowLayerColor();
+    method public float getShadowLayerDx();
+    method public float getShadowLayerDy();
+    method public float getShadowLayerRadius();
     method public float getStrikeThruPosition();
     method public float getStrikeThruThickness();
     method public android.graphics.Paint.Cap getStrokeCap();
@@ -14015,12 +14056,15 @@
     method public android.graphics.Paint.Style getStyle();
     method public android.graphics.Paint.Align getTextAlign();
     method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect);
+    method public void getTextBounds(java.lang.CharSequence, int, int, android.graphics.Rect);
     method public void getTextBounds(char[], int, int, android.graphics.Rect);
     method public java.util.Locale getTextLocale();
     method public android.os.LocaleList getTextLocales();
     method public void getTextPath(char[], int, int, float, float, android.graphics.Path);
     method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path);
     method public float getTextRunAdvances(char[], int, int, int, int, boolean, float[], int);
+    method public int getTextRunCursor(char[], int, int, boolean, int, int);
+    method public int getTextRunCursor(java.lang.CharSequence, int, int, boolean, int, int);
     method public float getTextScaleX();
     method public float getTextSize();
     method public float getTextSkewX();
@@ -14087,6 +14131,11 @@
     method public void setWordSpacing(float);
     method public android.graphics.Xfermode setXfermode(android.graphics.Xfermode);
     field public static final int ANTI_ALIAS_FLAG = 1; // 0x1
+    field public static final int CURSOR_AFTER = 0; // 0x0
+    field public static final int CURSOR_AT = 4; // 0x4
+    field public static final int CURSOR_AT_OR_AFTER = 1; // 0x1
+    field public static final int CURSOR_AT_OR_BEFORE = 3; // 0x3
+    field public static final int CURSOR_BEFORE = 2; // 0x2
     field public static final int DEV_KERN_TEXT_FLAG = 256; // 0x100
     field public static final int DITHER_FLAG = 4; // 0x4
     field public static final int EMBEDDED_BITMAP_TEXT_FLAG = 1024; // 0x400
@@ -15301,7 +15350,7 @@
     method public static java.lang.String toFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
   }
 
-  public class SystemFonts {
+  public final class SystemFonts {
     method public static java.util.Set<android.graphics.fonts.Font> getAvailableFonts();
   }
 
@@ -15926,6 +15975,14 @@
 
 package android.hardware.biometrics {
 
+  public class BiometricManager {
+    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 {
     method public void authenticate(android.hardware.biometrics.BiometricPrompt.CryptoObject, android.os.CancellationSignal, java.util.concurrent.Executor, android.hardware.biometrics.BiometricPrompt.AuthenticationCallback);
     method public void authenticate(android.os.CancellationSignal, java.util.concurrent.Executor, android.hardware.biometrics.BiometricPrompt.AuthenticationCallback);
@@ -18631,6 +18688,114 @@
     method public java.lang.CharSequence getName();
   }
 
+  public class Bidi {
+    ctor public Bidi();
+    ctor public Bidi(int, int);
+    ctor public Bidi(java.lang.String, int);
+    ctor public Bidi(java.text.AttributedCharacterIterator);
+    ctor public Bidi(char[], int, byte[], int, int, int);
+    method public boolean baseIsLeftToRight();
+    method public int countParagraphs();
+    method public int countRuns();
+    method public android.icu.text.Bidi createLineBidi(int, int);
+    method public static byte getBaseDirection(java.lang.CharSequence);
+    method public int getBaseLevel();
+    method public android.icu.text.BidiClassifier getCustomClassifier();
+    method public int getCustomizedClass(int);
+    method public byte getDirection();
+    method public int getLength();
+    method public byte getLevelAt(int);
+    method public byte[] getLevels();
+    method public int getLogicalIndex(int);
+    method public int[] getLogicalMap();
+    method public android.icu.text.BidiRun getLogicalRun(int);
+    method public byte getParaLevel();
+    method public android.icu.text.BidiRun getParagraph(int);
+    method public android.icu.text.BidiRun getParagraphByIndex(int);
+    method public int getParagraphIndex(int);
+    method public int getProcessedLength();
+    method public int getReorderingMode();
+    method public int getReorderingOptions();
+    method public int getResultLength();
+    method public int getRunCount();
+    method public int getRunLevel(int);
+    method public int getRunLimit(int);
+    method public int getRunStart(int);
+    method public char[] getText();
+    method public java.lang.String getTextAsString();
+    method public int getVisualIndex(int);
+    method public int[] getVisualMap();
+    method public android.icu.text.BidiRun getVisualRun(int);
+    method public static int[] invertMap(int[]);
+    method public boolean isInverse();
+    method public boolean isLeftToRight();
+    method public boolean isMixed();
+    method public boolean isOrderParagraphsLTR();
+    method public boolean isRightToLeft();
+    method public void orderParagraphsLTR(boolean);
+    method public static int[] reorderLogical(byte[]);
+    method public static int[] reorderVisual(byte[]);
+    method public static void reorderVisually(byte[], int, java.lang.Object[], int, int);
+    method public static boolean requiresBidi(char[], int, int);
+    method public void setContext(java.lang.String, java.lang.String);
+    method public void setCustomClassifier(android.icu.text.BidiClassifier);
+    method public void setInverse(boolean);
+    method public android.icu.text.Bidi setLine(int, int);
+    method public void setPara(java.lang.String, byte, byte[]);
+    method public void setPara(char[], byte, byte[]);
+    method public void setPara(java.text.AttributedCharacterIterator);
+    method public void setReorderingMode(int);
+    method public void setReorderingOptions(int);
+    method public java.lang.String writeReordered(int);
+    method public static java.lang.String writeReverse(java.lang.String, int);
+    field public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = 126; // 0x7e
+    field public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = 127; // 0x7f
+    field public static final int DIRECTION_LEFT_TO_RIGHT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT_TO_LEFT = 1; // 0x1
+    field public static final short DO_MIRRORING = 2; // 0x2
+    field public static final short INSERT_LRM_FOR_NUMERIC = 4; // 0x4
+    field public static final short KEEP_BASE_COMBINING = 1; // 0x1
+    field public static final byte LEVEL_DEFAULT_LTR = 126; // 0x7e
+    field public static final byte LEVEL_DEFAULT_RTL = 127; // 0x7f
+    field public static final byte LEVEL_OVERRIDE = -128; // 0xffffff80
+    field public static final byte LTR = 0; // 0x0
+    field public static final int MAP_NOWHERE = -1; // 0xffffffff
+    field public static final byte MAX_EXPLICIT_LEVEL = 125; // 0x7d
+    field public static final byte MIXED = 2; // 0x2
+    field public static final byte NEUTRAL = 3; // 0x3
+    field public static final int OPTION_DEFAULT = 0; // 0x0
+    field public static final int OPTION_INSERT_MARKS = 1; // 0x1
+    field public static final int OPTION_REMOVE_CONTROLS = 2; // 0x2
+    field public static final int OPTION_STREAMING = 4; // 0x4
+    field public static final short OUTPUT_REVERSE = 16; // 0x10
+    field public static final short REMOVE_BIDI_CONTROLS = 8; // 0x8
+    field public static final short REORDER_DEFAULT = 0; // 0x0
+    field public static final short REORDER_GROUP_NUMBERS_WITH_R = 2; // 0x2
+    field public static final short REORDER_INVERSE_FOR_NUMBERS_SPECIAL = 6; // 0x6
+    field public static final short REORDER_INVERSE_LIKE_DIRECT = 5; // 0x5
+    field public static final short REORDER_INVERSE_NUMBERS_AS_L = 4; // 0x4
+    field public static final short REORDER_NUMBERS_SPECIAL = 1; // 0x1
+    field public static final short REORDER_RUNS_ONLY = 3; // 0x3
+    field public static final byte RTL = 1; // 0x1
+  }
+
+  public class BidiClassifier {
+    ctor public BidiClassifier(java.lang.Object);
+    method public int classify(int);
+    method public java.lang.Object getContext();
+    method public void setContext(java.lang.Object);
+  }
+
+  public class BidiRun {
+    method public byte getDirection();
+    method public byte getEmbeddingLevel();
+    method public int getLength();
+    method public int getLimit();
+    method public int getStart();
+    method public boolean isEvenRun();
+    method public boolean isOddRun();
+  }
+
   public abstract class BreakIterator implements java.lang.Cloneable {
     ctor protected BreakIterator();
     method public java.lang.Object clone();
@@ -21502,7 +21667,7 @@
     method public android.view.inputmethod.InputConnection getCurrentInputConnection();
     method public android.view.inputmethod.EditorInfo getCurrentInputEditorInfo();
     method public boolean getCurrentInputStarted();
-    method public int getInputMethodWindowRecommendedHeight();
+    method public deprecated int getInputMethodWindowRecommendedHeight();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getMaxWidth();
     method public java.lang.CharSequence getTextForImeAction(int);
@@ -27137,6 +27302,7 @@
     method public android.net.Network[] getAllNetworks();
     method public deprecated boolean getBackgroundDataSetting();
     method public android.net.Network getBoundNetworkForProcess();
+    method public int getConnectionOwnerUid(int, java.net.InetSocketAddress, java.net.InetSocketAddress);
     method public android.net.ProxyInfo getDefaultProxy();
     method public android.net.LinkProperties getLinkProperties(android.net.Network);
     method public int getMultipathPreference(android.net.Network);
@@ -32374,6 +32540,7 @@
 
   public class Build {
     ctor public Build();
+    method public static java.util.List<android.os.Build.Partition> getPartitions();
     method public static java.lang.String getRadioVersion();
     method public static java.lang.String getSerial();
     field public static final java.lang.String BOARD;
@@ -32402,6 +32569,14 @@
     field public static final java.lang.String USER;
   }
 
+  public static class Build.Partition {
+    ctor public Build.Partition();
+    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";
+  }
+
   public static class Build.VERSION {
     ctor public Build.VERSION();
     field public static final java.lang.String BASE_OS;
@@ -33284,6 +33459,7 @@
     method public static final void setThreadPriority(int) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
     method public static final deprecated boolean supportsProcesses();
     field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710
+    field public static final int INVALID_UID = -1; // 0xffffffff
     field public static final int LAST_APPLICATION_UID = 19999; // 0x4e1f
     field public static final int PHONE_UID = 1001; // 0x3e9
     field public static final int SIGNAL_KILL = 9; // 0x9
@@ -33575,6 +33751,7 @@
     field public static final java.lang.String DISALLOW_FUN = "no_fun";
     field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
     field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
+    field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY = "no_install_unknown_sources_globally";
     field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
     field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
     field public static final java.lang.String DISALLOW_NETWORK_RESET = "no_network_reset";
@@ -36795,6 +36972,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";
@@ -39920,6 +40098,7 @@
     method public int getDisabledShowContext();
     method public static boolean isActiveService(android.content.Context, android.content.ComponentName);
     method public android.os.IBinder onBind(android.content.Intent);
+    method public java.util.Set<java.lang.String> onGetSupportedVoiceActions(java.util.Set<java.lang.String>);
     method public void onLaunchVoiceAssistFromKeyguard();
     method public void onReady();
     method public void onShutdown();
@@ -39982,6 +40161,7 @@
     field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
     field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8
     field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
+    field public static final int SHOW_SOURCE_NOTIFICATION = 64; // 0x40
     field public static final int SHOW_SOURCE_PUSH_TO_TALK = 32; // 0x20
     field public static final int SHOW_WITH_ASSIST = 1; // 0x1
     field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2
@@ -41187,6 +41367,7 @@
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
+    field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800
     field public static final int PROPERTY_RTT = 1024; // 0x400
     field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
     field public static final int PROPERTY_WIFI = 8; // 0x8
@@ -41842,6 +42023,7 @@
     field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+    field public static final java.lang.String EXTRA_CALL_NETWORK_TYPE = "android.telecom.extra.CALL_NETWORK_TYPE";
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
@@ -42139,6 +42321,7 @@
     field public static final deprecated java.lang.String KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL = "restart_radio_on_pdp_fail_regular_deactivation_bool";
     field public static final java.lang.String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool";
     field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
+    field public static final java.lang.String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
     field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
     field public static final java.lang.String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
     field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
@@ -42400,6 +42583,13 @@
     field public static final int STATUS_UNKNOWN = 0; // 0x0
   }
 
+  public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+    method public void close();
+    method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsGroupCallSessionCallback);
+    method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsGroupCallSessionCallback);
+    method public android.telephony.mbms.GroupCall startGroupCall(java.util.concurrent.Executor, long, int[], int[], android.telephony.mbms.GroupCallCallback);
+  }
+
   public class MbmsStreamingSession implements java.lang.AutoCloseable {
     method public void close();
     method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsStreamingSessionCallback);
@@ -42408,7 +42598,7 @@
     method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, java.util.concurrent.Executor, android.telephony.mbms.StreamingServiceCallback);
   }
 
-  public class NeighboringCellInfo implements android.os.Parcelable {
+  public deprecated class NeighboringCellInfo implements android.os.Parcelable {
     ctor public deprecated NeighboringCellInfo();
     ctor public deprecated NeighboringCellInfo(int, int);
     ctor public NeighboringCellInfo(int, java.lang.String, int);
@@ -42780,7 +42970,9 @@
     method public java.util.List<android.telephony.SubscriptionInfo> getOpportunisticSubscriptions(int);
     method public static int[] getSubscriptionIds(int);
     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);
@@ -42794,6 +42986,7 @@
     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_SUBSCRIPTION_ID = -1; // 0xffffffff
   }
@@ -42865,7 +43058,6 @@
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
     method public java.lang.String getNai();
-    method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
     method public java.lang.String getNetworkCountryIso();
     method public java.lang.String getNetworkOperator();
     method public java.lang.String getNetworkOperatorName();
@@ -42930,6 +43122,7 @@
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
     field public static final java.lang.String ACTION_SECRET_CODE = "android.telephony.action.SECRET_CODE";
     field public static final java.lang.String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION";
+    field public static final java.lang.String ACTION_SMS_APP_SERVICE = "android.telephony.action.SMS_APP_SERVICE";
     field public static final java.lang.String ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
     field public static final int APPTYPE_CSIM = 4; // 0x4
     field public static final int APPTYPE_ISIM = 5; // 0x5
@@ -43167,6 +43360,36 @@
 
 }
 
+package android.telephony.emergency {
+
+  public final class EmergencyNumber implements android.os.Parcelable {
+    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 {
@@ -43346,6 +43569,29 @@
     field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR;
   }
 
+  public class GroupCall implements java.lang.AutoCloseable {
+    method public void close();
+    method public long getTmgi();
+    method public void updateGroupCall(int[], int[]);
+    field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
+    field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3
+    field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; // 0x6
+    field public static final int REASON_NONE = 0; // 0x0
+    field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5
+    field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4
+    field public static final int STATE_STALLED = 3; // 0x3
+    field public static final int STATE_STARTED = 2; // 0x2
+    field public static final int STATE_STOPPED = 1; // 0x1
+  }
+
+  public class GroupCallCallback {
+    ctor public GroupCallCallback();
+    method public void onBroadcastSignalStrengthUpdated(int);
+    method public void onError(int, java.lang.String);
+    method public void onGroupCallStateChanged(int, int);
+    field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff
+  }
+
   public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
     ctor public MbmsDownloadReceiver();
     method public void onReceive(android.content.Context, android.content.Intent);
@@ -43394,6 +43640,14 @@
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
   }
 
+  public class MbmsGroupCallSessionCallback {
+    ctor public MbmsGroupCallSessionCallback();
+    method public void onAvailableSaisUpdated(java.util.List<java.lang.Integer>, java.util.List<java.util.List<java.lang.Integer>>);
+    method public void onError(int, java.lang.String);
+    method public void onMiddlewareReady();
+    method public void onServiceInterfaceAvailable(java.lang.String, int);
+  }
+
   public class MbmsStreamingSessionCallback {
     ctor public MbmsStreamingSessionCallback();
     method public void onError(int, java.lang.String);
@@ -44028,6 +44282,8 @@
     field public float density;
     field public int[] drawableState;
     field public int linkColor;
+    field public int underlineColor;
+    field public float underlineThickness;
   }
 
   public class TextUtils {
@@ -44842,11 +45098,20 @@
     ctor public TextAppearanceSpan(android.os.Parcel);
     method public int describeContents();
     method public java.lang.String getFamily();
+    method public java.lang.String getFontFeatureSettings();
+    method public java.lang.String getFontVariationSettings();
     method public android.content.res.ColorStateList getLinkTextColor();
+    method public int getShadowColor();
+    method public float getShadowDx();
+    method public float getShadowDy();
+    method public float getShadowRadius();
     method public int getSpanTypeId();
     method public android.content.res.ColorStateList getTextColor();
+    method public int getTextFontWeight();
     method public int getTextSize();
     method public int getTextStyle();
+    method public android.graphics.Typeface getTypeface();
+    method public boolean isElegantTextHeight();
     method public void updateDrawState(android.text.TextPaint);
     method public void updateMeasureState(android.text.TextPaint);
     method public void writeToParcel(android.os.Parcel, int);
@@ -45489,6 +45754,7 @@
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
     method public V get(java.lang.Object);
     method public int indexOfKey(java.lang.Object);
+    method public int indexOfValue(java.lang.Object);
     method public boolean isEmpty();
     method public K keyAt(int);
     method public java.util.Set<K> keySet();
@@ -45509,6 +45775,7 @@
     ctor public ArraySet();
     ctor public ArraySet(int);
     ctor public ArraySet(android.util.ArraySet<E>);
+    ctor public ArraySet(java.util.Collection<? extends E>);
     method public boolean add(E);
     method public void addAll(android.util.ArraySet<? extends E>);
     method public boolean addAll(java.util.Collection<? extends E>);
@@ -46080,6 +46347,7 @@
     method public int keyAt(int);
     method public void put(int, boolean);
     method public void removeAt(int);
+    method public void setValueAt(int, boolean);
     method public int size();
     method public boolean valueAt(int);
   }
@@ -46098,6 +46366,7 @@
     method public int keyAt(int);
     method public void put(int, int);
     method public void removeAt(int);
+    method public void setValueAt(int, int);
     method public int size();
     method public int valueAt(int);
   }
@@ -46419,7 +46688,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();
@@ -50115,7 +50389,7 @@
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
-    method public boolean getDetachWallpaper();
+    method public deprecated boolean getDetachWallpaper();
     method public long getDuration();
     method public boolean getFillAfter();
     method public boolean getFillBefore();
@@ -50139,7 +50413,7 @@
     method public void scaleCurrentDuration(float);
     method public void setAnimationListener(android.view.animation.Animation.AnimationListener);
     method public void setBackgroundColor(int);
-    method public void setDetachWallpaper(boolean);
+    method public deprecated void setDetachWallpaper(boolean);
     method public void setDuration(long);
     method public void setFillAfter(boolean);
     method public void setFillBefore(boolean);
@@ -51232,7 +51506,7 @@
   }
 
   public abstract class CookieManager {
-    ctor public CookieManager();
+    ctor public deprecated CookieManager();
     method public abstract boolean acceptCookie();
     method public abstract boolean acceptThirdPartyCookies(android.webkit.WebView);
     method public static boolean allowFileSchemeCookies();
@@ -51332,13 +51606,13 @@
   }
 
   public abstract class RenderProcessGoneDetail {
-    ctor public RenderProcessGoneDetail();
+    ctor public deprecated RenderProcessGoneDetail();
     method public abstract boolean didCrash();
     method public abstract int rendererPriorityAtExit();
   }
 
   public abstract class SafeBrowsingResponse {
-    ctor public SafeBrowsingResponse();
+    ctor public deprecated SafeBrowsingResponse();
     method public abstract void backToSafety(boolean);
     method public abstract void proceed(boolean);
     method public abstract void showInterstitial(boolean);
@@ -51350,7 +51624,7 @@
   }
 
   public abstract class ServiceWorkerController {
-    ctor public ServiceWorkerController();
+    ctor public deprecated ServiceWorkerController();
     method public static android.webkit.ServiceWorkerController getInstance();
     method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings();
     method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient);
@@ -51399,7 +51673,7 @@
   }
 
   public abstract class TracingController {
-    ctor public TracingController();
+    ctor public deprecated TracingController();
     method public static android.webkit.TracingController getInstance();
     method public abstract boolean isTracing();
     method public abstract void start(android.webkit.TracingConfig);
@@ -51939,7 +52213,7 @@
   }
 
   public abstract class WebViewDatabase {
-    ctor public WebViewDatabase();
+    ctor public deprecated WebViewDatabase();
     method public abstract deprecated void clearFormData();
     method public abstract void clearHttpAuthUsernamePassword();
     method public abstract deprecated void clearUsernamePassword();
@@ -53219,7 +53493,7 @@
   }
 
   public final class Magnifier {
-    ctor public Magnifier(android.view.View);
+    ctor public deprecated Magnifier(android.view.View);
     method public void dismiss();
     method public float getCornerRadius();
     method public int getDefaultHorizontalSourceToMagnifierOffset();
@@ -55047,6 +55321,7 @@
   public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
     ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader);
     ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader);
+    ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader, boolean);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
diff --git a/api/removed.txt b/api/removed.txt
index b6dabcd..f7106d2 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -545,6 +545,7 @@
   }
 
   public class TelephonyManager {
+    method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
     method public deprecated android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback);
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index 47b4cfc..30a0c85 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -128,6 +128,7 @@
     field public static final java.lang.String PEERS_MAC_ADDRESS = "android.permission.PEERS_MAC_ADDRESS";
     field public static final java.lang.String PERFORM_CDMA_PROVISIONING = "android.permission.PERFORM_CDMA_PROVISIONING";
     field public static final java.lang.String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
+    field public static final java.lang.String POWER_SAVER = "android.permission.POWER_SAVER";
     field public static final java.lang.String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
     field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
@@ -950,6 +951,7 @@
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String NETWORK_SCORE_SERVICE = "network_score";
     field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock";
+    field public static final java.lang.String PERMISSION_SERVICE = "permission";
     field public static final java.lang.String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block";
     field public static final java.lang.String SECURE_ELEMENT_SERVICE = "secure_element";
     field public static final java.lang.String STATS_MANAGER = "stats";
@@ -1116,9 +1118,9 @@
   }
 
   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
@@ -3994,6 +3996,7 @@
   }
 
   public final class PowerManager {
+    method public boolean setPowerSaveMode(boolean);
     method public void userActivity(long, int, int);
     field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
     field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
@@ -4192,6 +4195,20 @@
 
 }
 
+package android.permission {
+
+  public final class PermissionManager {
+    method public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
+  }
+
+  public static final class PermissionManager.SplitPermissionInfo {
+    method public java.lang.String[] getNewPermissions();
+    method public java.lang.String getRootPermission();
+    method public int getTargetSdk();
+  }
+
+}
+
 package android.permissionpresenterservice {
 
   public abstract class RuntimePermissionPresenterService extends android.app.Service {
@@ -4424,6 +4441,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";
@@ -5223,6 +5241,7 @@
     method public deprecated android.content.ComponentName getDefaultPhoneApp();
     method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
     method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
+    method public boolean isInEmergencyCall();
     method public boolean isRinging();
     method public boolean isTtySupported();
     field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
@@ -5249,6 +5268,10 @@
     field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
   }
 
+  public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+    field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall";
+  }
+
   public class MbmsStreamingSession implements java.lang.AutoCloseable {
     field public static final java.lang.String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
   }
@@ -5308,9 +5331,12 @@
   }
 
   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 {
@@ -5405,7 +5431,6 @@
   }
 
   public class TelephonyManager {
-    method public deprecated void answerRingingCall();
     method public deprecated void call(java.lang.String, java.lang.String);
     method public int checkCarrierPrivilegesForPackage(java.lang.String);
     method public int checkCarrierPrivilegesForPackageAnyPhone(java.lang.String);
@@ -5413,7 +5438,7 @@
     method public boolean disableDataConnectivity();
     method public boolean enableDataConnectivity();
     method public void enableVideoCalling(boolean);
-    method public deprecated boolean endCall();
+    method public java.lang.String getAidForAppType(int);
     method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -5428,6 +5453,8 @@
     method public deprecated boolean getDataEnabled();
     method public deprecated boolean getDataEnabled(int);
     method public boolean getEmergencyCallbackMode();
+    method public java.lang.String getIsimDomain();
+    method public int getPreferredNetworkType(int);
     method public int getSimApplicationState();
     method public int getSimCardState();
     method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
@@ -5437,10 +5464,7 @@
     method public boolean handlePinMmi(java.lang.String);
     method public boolean handlePinMmiForSubscriber(int, java.lang.String);
     method public boolean isDataConnectivityPossible();
-    method public deprecated boolean isIdle();
-    method public deprecated boolean isOffhook();
     method public deprecated boolean isRadioOn();
-    method public deprecated boolean isRinging();
     method public boolean isVideoCallingEnabled();
     method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean needsOtaServiceProvisioning();
@@ -5454,7 +5478,6 @@
     method public void setSimPowerStateForSlot(int, int);
     method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
     method public void setVoiceActivationState(int);
-    method public deprecated void silenceRinger();
     method public boolean supplyPin(java.lang.String);
     method public int[] supplyPinReportResult(java.lang.String);
     method public boolean supplyPuk(java.lang.String, java.lang.String);
@@ -5472,6 +5495,29 @@
     field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4
+    field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5
+    field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6
+    field public static final int NETWORK_MODE_GLOBAL = 7; // 0x7
+    field public static final int NETWORK_MODE_GSM_ONLY = 1; // 0x1
+    field public static final int NETWORK_MODE_GSM_UMTS = 3; // 0x3
+    field public static final int NETWORK_MODE_LTE_CDMA_EVDO = 8; // 0x8
+    field public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; // 0xa
+    field public static final int NETWORK_MODE_LTE_GSM_WCDMA = 9; // 0x9
+    field public static final int NETWORK_MODE_LTE_ONLY = 11; // 0xb
+    field public static final int NETWORK_MODE_LTE_TDSCDMA = 15; // 0xf
+    field public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; // 0x16
+    field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; // 0x11
+    field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; // 0x14
+    field public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; // 0x13
+    field public static final int NETWORK_MODE_LTE_WCDMA = 12; // 0xc
+    field public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; // 0x15
+    field public static final int NETWORK_MODE_TDSCDMA_GSM = 16; // 0x10
+    field public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; // 0x12
+    field public static final int NETWORK_MODE_TDSCDMA_ONLY = 13; // 0xd
+    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 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
@@ -5807,6 +5853,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_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";
@@ -6551,6 +6598,17 @@
     method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
   }
 
+  public class MbmsGroupCallServiceBase extends android.app.Service {
+    ctor public MbmsGroupCallServiceBase();
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback);
+    method public void stopGroupCall(int, long);
+    method public void updateGroupCall(int, long, int[], int[]);
+  }
+
   public class MbmsStreamingServiceBase extends android.os.Binder {
     ctor public MbmsStreamingServiceBase();
     method public void dispose(int) throws android.os.RemoteException;
diff --git a/api/system-removed.txt b/api/system-removed.txt
index b88c760..2246562 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -143,3 +143,16 @@
 
 }
 
+package android.telephony {
+
+  public class TelephonyManager {
+    method public deprecated void answerRingingCall();
+    method public deprecated boolean endCall();
+    method public deprecated boolean isIdle();
+    method public deprecated boolean isOffhook();
+    method public deprecated boolean isRinging();
+    method public deprecated void silenceRinger();
+  }
+
+}
+
diff --git a/api/test-current.txt b/api/test-current.txt
index e22f516..937c266 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);
@@ -708,6 +709,10 @@
     method public void removeSyncBarrier(int);
   }
 
+  public final class PowerManager {
+    method public boolean setPowerSaveMode(boolean);
+  }
+
   public class Process {
     method public static final int getThreadScheduler(int) throws java.lang.IllegalArgumentException;
   }
@@ -946,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";
   }
 
@@ -1181,6 +1187,10 @@
     field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override";
   }
 
+  public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+    field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA = "mbms-group-call-service-override";
+  }
+
   public class MbmsStreamingSession implements java.lang.AutoCloseable {
     field public static final java.lang.String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
   }
@@ -1250,6 +1260,17 @@
     method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
   }
 
+  public class MbmsGroupCallServiceBase extends android.app.Service {
+    ctor public MbmsGroupCallServiceBase();
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback);
+    method public void stopGroupCall(int, long);
+    method public void updateGroupCall(int, long, int[], int[]);
+  }
+
   public class MbmsStreamingServiceBase extends android.os.Binder {
     ctor public MbmsStreamingServiceBase();
     method public void dispose(int) throws android.os.RemoteException;
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 36e51b9..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
@@ -470,7 +466,8 @@
                     onExecute(provider);
                 } finally {
                     if (provider != null) {
-                        activityManager.removeContentProviderExternal(providerName, token);
+                        activityManager.removeContentProviderExternalAsUser(
+                                providerName, token, mUserId);
                     }
                 }
             } catch (Exception e) {
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index e14f2eb..d334f96 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -198,8 +198,7 @@
 
     sp<GraphicBuffer> outBuffer;
     status_t result = ScreenshotClient::capture(display, Rect(), 0 /* reqWidth */,
-            0 /* reqHeight */, INT32_MIN, INT32_MAX, /* all layers */ false, captureOrientation,
-            &outBuffer);
+            0 /* reqHeight */, false, captureOrientation, &outBuffer);
     if (result != NO_ERROR) {
         close(fd);
         return 1;
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 5e87ef6..f6b0db8 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -67,7 +67,9 @@
     src/subscriber/SubscriberReporter.cpp \
     src/HashableDimensionKey.cpp \
     src/guardrail/StatsdStats.cpp \
-    src/socket/StatsSocketListener.cpp
+    src/socket/StatsSocketListener.cpp \
+    src/shell/ShellSubscriber.cpp \
+    src/shell/shell_config.proto
 
 # TODO(b/110563449): Once statsd is using a blueprint file, migrate to the proper filegroups.
 statsd_common_src += \
@@ -97,6 +99,7 @@
     libhidlbase \
     libhidltransport \
     libhwbinder \
+    android.frameworks.stats@1.0 \
     android.hardware.health@2.0 \
     android.hardware.power@1.0 \
     android.hardware.power@1.1 \
@@ -144,10 +147,10 @@
 LOCAL_MODULE_CLASS := EXECUTABLES
 
 # Enable sanitizer ONLY on eng builds.
-ifeq ($(TARGET_BUILD_VARIANT),eng)
-    LOCAL_CLANG := true
-    LOCAL_SANITIZE := address
-endif
+#ifeq ($(TARGET_BUILD_VARIANT),eng)
+#    LOCAL_CLANG := true
+#    LOCAL_SANITIZE := address
+#endif
 
 # Add a flag to enable stats log printing from statsd on debug builds.
 ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
@@ -225,7 +228,8 @@
     tests/e2e/Anomaly_count_e2e_test.cpp \
     tests/e2e/Anomaly_duration_sum_e2e_test.cpp \
     tests/e2e/ConfigTtl_e2e_test.cpp \
-    tests/e2e/PartialBucket_e2e_test.cpp
+    tests/e2e/PartialBucket_e2e_test.cpp \
+    tests/shell/ShellSubscriber_test.cpp
 
 LOCAL_STATIC_LIBRARIES := \
     $(statsd_common_static_libraries) \
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index 7b6d29b..fc1a61c 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -147,6 +147,9 @@
         case STRING:
             str_value = from.str_value;
             break;
+        case STORAGE:
+            storage_value = from.storage_value;
+            break;
         default:
             break;
     }
@@ -164,6 +167,8 @@
             return std::to_string(double_value) + "[D]";
         case STRING:
             return str_value + "[S]";
+        case STORAGE:
+            return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
         default:
             return "[UNKNOWN]";
     }
@@ -183,6 +188,8 @@
             return double_value == that.double_value;
         case STRING:
             return str_value == that.str_value;
+        case STORAGE:
+            return storage_value == that.storage_value;
         default:
             return false;
     }
@@ -201,6 +208,8 @@
             return double_value != that.double_value;
         case STRING:
             return str_value != that.str_value;
+        case STORAGE:
+            return storage_value != that.storage_value;
         default:
             return false;
     }
@@ -220,6 +229,8 @@
             return double_value < that.double_value;
         case STRING:
             return str_value < that.str_value;
+        case STORAGE:
+            return storage_value < that.storage_value;
         default:
             return false;
     }
@@ -239,6 +250,8 @@
             return double_value > that.double_value;
         case STRING:
             return str_value > that.str_value;
+        case STORAGE:
+            return storage_value > that.storage_value;
         default:
             return false;
     }
@@ -258,6 +271,8 @@
             return double_value >= that.double_value;
         case STRING:
             return str_value >= that.str_value;
+        case STORAGE:
+            return storage_value >= that.storage_value;
         default:
             return false;
     }
@@ -274,6 +289,11 @@
         return v;
     }
 
+    if (type == STORAGE) {
+        ALOGE("Can't operate on storage value type");
+        return v;
+    }
+
     switch (type) {
         case INT:
             v.setInt(int_value - that.int_value);
@@ -311,6 +331,9 @@
         case STRING:
             str_value = that.str_value;
             break;
+        case STORAGE:
+            storage_value = that.storage_value;
+            break;
         default:
             break;
     }
@@ -326,6 +349,10 @@
         ALOGE("Can't operate on string value type");
         return *this;
     }
+    if (type == STORAGE) {
+        ALOGE("Can't operate on storage value type");
+        return *this;
+    }
 
     switch (type) {
         case INT:
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index b1b885e..77163f9 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -32,7 +32,7 @@
 const int32_t kClearLastBitDeco = 0x7f;
 const int32_t kClearAllPositionMatcherMask = 0xffff00ff;
 
-enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING };
+enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE };
 
 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
 
@@ -293,6 +293,11 @@
         type = STRING;
     }
 
+    Value(const std::vector<uint8_t>& v) {
+        storage_value = v;
+        type = STORAGE;
+    }
+
     void setInt(int32_t v) {
         int_value = v;
         type = INT;
@@ -320,6 +325,7 @@
         double double_value;
     };
     std::string str_value;
+    std::vector<uint8_t> storage_value;
 
     Type type;
 
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 8e02f9c..f4c70be 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -257,12 +257,18 @@
     return it->second->byteSize();
 }
 
-void StatsLogProcessor::dumpStates(FILE* out, bool verbose) {
+void StatsLogProcessor::dumpStates(int out, bool verbose) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
-    fprintf(out, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
-    for (auto metricsManager : mMetricsManagers) {
-        metricsManager.second->dumpStates(out, verbose);
+    FILE* fout = fdopen(out, "w");
+    if (fout == NULL) {
+        return;
     }
+    fprintf(fout, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
+    for (auto metricsManager : mMetricsManagers) {
+        metricsManager.second->dumpStates(fout, verbose);
+    }
+
+    fclose(fout);
 }
 
 /*
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index df80b8e..4091d95 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -83,7 +83,7 @@
         return mUidMap;
     }
 
-    void dumpStates(FILE* out, bool verbose);
+    void dumpStates(int outFd, bool verbose);
 
     void informPullAlarmFired(const int64_t timestampNs);
 
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 9a79345..8da2d44 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -34,13 +34,14 @@
 #include <dirent.h>
 #include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
 #include <private/android_filesystem_config.h>
-#include <utils/Looper.h>
-#include <utils/String16.h>
 #include <statslog.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/system_properties.h>
 #include <unistd.h>
+#include <utils/Looper.h>
+#include <utils/String16.h>
+#include <chrono>
 
 using namespace android;
 
@@ -214,30 +215,8 @@
             sp<IResultReceiver> resultReceiver =
                     IResultReceiver::asInterface(data.readStrongBinder());
 
-            FILE* fin = fdopen(in, "r");
-            FILE* fout = fdopen(out, "w");
-            FILE* ferr = fdopen(err, "w");
-
-            if (fin == NULL || fout == NULL || ferr == NULL) {
-                resultReceiver->send(NO_MEMORY);
-            } else {
-                err = command(fin, fout, ferr, args);
-                resultReceiver->send(err);
-            }
-
-            if (fin != NULL) {
-                fflush(fin);
-                fclose(fin);
-            }
-            if (fout != NULL) {
-                fflush(fout);
-                fclose(fout);
-            }
-            if (fout != NULL) {
-                fflush(ferr);
-                fclose(ferr);
-            }
-
+            err = command(in, out, err, args, resultReceiver);
+            resultReceiver->send(err);
             return NO_ERROR;
         }
         default: { return BnStatsManager::onTransact(code, data, reply, flags); }
@@ -251,10 +230,6 @@
     if (!checkCallingPermission(String16(kPermissionDump))) {
         return PERMISSION_DENIED;
     }
-    FILE* out = fdopen(fd, "w");
-    if (out == NULL) {
-        return NO_MEMORY;  // the fd is already open
-    }
 
     bool verbose = false;
     bool proto = false;
@@ -265,21 +240,20 @@
         proto = true;
     }
 
-    dump_impl(out, verbose, proto);
+    dump_impl(fd, verbose, proto);
 
-    fclose(out);
     return NO_ERROR;
 }
 
 /**
  * Write debugging data about statsd in text or proto format.
  */
-void StatsService::dump_impl(FILE* out, bool verbose, bool proto) {
+void StatsService::dump_impl(int out, bool verbose, bool proto) {
     if (proto) {
         vector<uint8_t> data;
         StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
         for (size_t i = 0; i < data.size(); i ++) {
-            fprintf(out, "%c", data[i]);
+            dprintf(out, "%c", data[i]);
         }
     } else {
         StatsdStats::getInstance().dumpStats(out);
@@ -290,7 +264,8 @@
 /**
  * Implementation of the adb shell cmd stats command.
  */
-status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
+status_t StatsService::command(int in, int out, int err, Vector<String8>& args,
+                               sp<IResultReceiver> resultReceiver) {
     uid_t uid = IPCThreadState::self()->getCallingUid();
     if (uid != AID_ROOT && uid != AID_SHELL) {
         return PERMISSION_DENIED;
@@ -342,97 +317,106 @@
         if (!args[0].compare(String8("print-logs"))) {
             return cmd_print_logs(out, args);
         }
+        if (!args[0].compare(String8("data-subscribe"))) {
+            if (mShellSubscriber == nullptr) {
+                mShellSubscriber = new ShellSubscriber(mUidMap);
+            }
+            mShellSubscriber->startNewSubscription(in, out, resultReceiver);
+            return NO_ERROR;
+        }
     }
 
     print_cmd_help(out);
     return NO_ERROR;
 }
 
-void StatsService::print_cmd_help(FILE* out) {
-    fprintf(out,
+void StatsService::print_cmd_help(int out) {
+    dprintf(out,
             "usage: adb shell cmd stats print-stats-log [tag_required] "
             "[timestamp_nsec_optional]\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats meminfo\n");
-    fprintf(out, "\n");
-    fprintf(out, "  Prints the malloc debug information. You need to run the following first: \n");
-    fprintf(out, "   # adb shell stop\n");
-    fprintf(out, "   # adb shell setprop libc.debug.malloc.program statsd \n");
-    fprintf(out, "   # adb shell setprop libc.debug.malloc.options backtrace \n");
-    fprintf(out, "   # adb shell start\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
-    fprintf(out, "\n");
-    fprintf(out, "  Prints the UID, app name, version mapping.\n");
-    fprintf(out, "  PKG           Optional package name to print the uids of the package\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats pull-source [int] \n");
-    fprintf(out, "\n");
-    fprintf(out, "  Prints the output of a pulled metrics source (int indicates source)\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats write-to-disk \n");
-    fprintf(out, "\n");
-    fprintf(out, "  Flushes all data on memory to disk.\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
-    fprintf(out, "  Writes an AppBreadcrumbReported event to the statslog buffer.\n");
-    fprintf(out, "  UID           The uid to use. It is only possible to pass a UID\n");
-    fprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
-    fprintf(out, "                uid is used.\n");
-    fprintf(out, "  LABEL         Integer in [0, 15], as per atoms.proto.\n");
-    fprintf(out, "  STATE         Integer in [0, 3], as per atoms.proto.\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
-    fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
-    fprintf(out, "\n");
-    fprintf(out, "  Adds, updates or removes a configuration. The proto should be in\n");
-    fprintf(out, "  wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
-    fprintf(out, "  provided, then all configs will be removed from memory and disk.\n");
-    fprintf(out, "\n");
-    fprintf(out, "  UID           The uid to use. It is only possible to pass the UID\n");
-    fprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
-    fprintf(out, "                uid is used.\n");
-    fprintf(out, "  NAME          The per-uid name to use\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n              *Note: If both UID and NAME are omitted then all configs will\n");
-    fprintf(out, "\n                     be removed from memory and disk!\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats dump-report [UID] NAME [--include_current_bucket] [--proto]\n");
-    fprintf(out, "  Dump all metric data for a configuration.\n");
-    fprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
-    fprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
-    fprintf(out, "                calling uid is used.\n");
-    fprintf(out, "  NAME          The name of the configuration\n");
-    fprintf(out, "  --proto       Print proto binary.\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
-    fprintf(out, "  Send a broadcast that triggers the subscriber to fetch metrics.\n");
-    fprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
-    fprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
-    fprintf(out, "                calling uid is used.\n");
-    fprintf(out, "  NAME          The name of the configuration\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats print-stats\n");
-    fprintf(out, "  Prints some basic stats.\n");
-    fprintf(out, "  --proto       Print proto binary instead of string format.\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
-    fprintf(out, "  Clear cached puller data.\n");
-    fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats print-logs\n");
-    fprintf(out, "      Only works on eng build\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats meminfo\n");
+    dprintf(out, "\n");
+    dprintf(out, "  Prints the malloc debug information. You need to run the following first: \n");
+    dprintf(out, "   # adb shell stop\n");
+    dprintf(out, "   # adb shell setprop libc.debug.malloc.program statsd \n");
+    dprintf(out, "   # adb shell setprop libc.debug.malloc.options backtrace \n");
+    dprintf(out, "   # adb shell start\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
+    dprintf(out, "\n");
+    dprintf(out, "  Prints the UID, app name, version mapping.\n");
+    dprintf(out, "  PKG           Optional package name to print the uids of the package\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats pull-source [int] \n");
+    dprintf(out, "\n");
+    dprintf(out, "  Prints the output of a pulled metrics source (int indicates source)\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats write-to-disk \n");
+    dprintf(out, "\n");
+    dprintf(out, "  Flushes all data on memory to disk.\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
+    dprintf(out, "  Writes an AppBreadcrumbReported event to the statslog buffer.\n");
+    dprintf(out, "  UID           The uid to use. It is only possible to pass a UID\n");
+    dprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
+    dprintf(out, "                uid is used.\n");
+    dprintf(out, "  LABEL         Integer in [0, 15], as per atoms.proto.\n");
+    dprintf(out, "  STATE         Integer in [0, 3], as per atoms.proto.\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
+    dprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
+    dprintf(out, "\n");
+    dprintf(out, "  Adds, updates or removes a configuration. The proto should be in\n");
+    dprintf(out, "  wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
+    dprintf(out, "  provided, then all configs will be removed from memory and disk.\n");
+    dprintf(out, "\n");
+    dprintf(out, "  UID           The uid to use. It is only possible to pass the UID\n");
+    dprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
+    dprintf(out, "                uid is used.\n");
+    dprintf(out, "  NAME          The per-uid name to use\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n              *Note: If both UID and NAME are omitted then all configs will\n");
+    dprintf(out, "\n                     be removed from memory and disk!\n");
+    dprintf(out, "\n");
+    dprintf(out,
+            "usage: adb shell cmd stats dump-report [UID] NAME [--include_current_bucket] "
+            "[--proto]\n");
+    dprintf(out, "  Dump all metric data for a configuration.\n");
+    dprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
+    dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
+    dprintf(out, "                calling uid is used.\n");
+    dprintf(out, "  NAME          The name of the configuration\n");
+    dprintf(out, "  --proto       Print proto binary.\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
+    dprintf(out, "  Send a broadcast that triggers the subscriber to fetch metrics.\n");
+    dprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
+    dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
+    dprintf(out, "                calling uid is used.\n");
+    dprintf(out, "  NAME          The name of the configuration\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats print-stats\n");
+    dprintf(out, "  Prints some basic stats.\n");
+    dprintf(out, "  --proto       Print proto binary instead of string format.\n");
+    dprintf(out, "\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
+    dprintf(out, "  Clear cached puller data.\n");
+    dprintf(out, "\n");
+    dprintf(out, "usage: adb shell cmd stats print-logs\n");
+    dprintf(out, "      Only works on eng build\n");
 }
 
-status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) {
+status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) {
     string name;
     bool good = false;
     int uid;
@@ -456,9 +440,9 @@
                 }
             }
         } else {
-            fprintf(out,
+            dprintf(out,
                     "The metrics can only be dumped for other UIDs on eng or userdebug "
-                            "builds.\n");
+                    "builds.\n");
         }
     }
     if (!good) {
@@ -481,7 +465,7 @@
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
+status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& args) {
     const int argCount = args.size();
     if (argCount >= 2) {
         if (args[1] == "update" || args[1] == "remove") {
@@ -508,7 +492,7 @@
                         }
                     }
                 } else {
-                    fprintf(err,
+                    dprintf(err,
                             "The config can only be set for other UIDs on eng or userdebug "
                             "builds.\n");
                 }
@@ -526,21 +510,21 @@
                 char* endp;
                 int64_t configID = strtoll(name.c_str(), &endp, 10);
                 if (endp == name.c_str() || *endp != '\0') {
-                    fprintf(err, "Error parsing config ID.\n");
+                    dprintf(err, "Error parsing config ID.\n");
                     return UNKNOWN_ERROR;
                 }
 
                 // Read stream into buffer.
                 string buffer;
-                if (!android::base::ReadFdToString(fileno(in), &buffer)) {
-                    fprintf(err, "Error reading stream for StatsConfig.\n");
+                if (!android::base::ReadFdToString(in, &buffer)) {
+                    dprintf(err, "Error reading stream for StatsConfig.\n");
                     return UNKNOWN_ERROR;
                 }
 
                 // Parse buffer.
                 StatsdConfig config;
                 if (!config.ParseFromString(buffer)) {
-                    fprintf(err, "Error parsing proto stream for StatsConfig.\n");
+                    dprintf(err, "Error parsing proto stream for StatsConfig.\n");
                     return UNKNOWN_ERROR;
                 }
 
@@ -562,7 +546,7 @@
     return UNKNOWN_ERROR;
 }
 
-status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args) {
+status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& args) {
     if (mProcessor != nullptr) {
         int argCount = args.size();
         bool good = false;
@@ -597,7 +581,7 @@
                     }
                 }
             } else {
-                fprintf(out,
+                dprintf(out,
                         "The metrics can only be dumped for other UIDs on eng or userdebug "
                         "builds.\n");
             }
@@ -608,11 +592,11 @@
                                      includeCurrentBucket, ADB_DUMP, &data);
             if (proto) {
                 for (size_t i = 0; i < data.size(); i ++) {
-                    fprintf(out, "%c", data[i]);
+                    dprintf(out, "%c", data[i]);
                 }
             } else {
-                fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
-                fprintf(out, "See the StatsLogReport in logcat...\n");
+                dprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
+                dprintf(out, "See the StatsLogReport in logcat...\n");
             }
             return android::OK;
         } else {
@@ -621,12 +605,12 @@
             return UNKNOWN_ERROR;
         }
     } else {
-        fprintf(out, "Log processor does not exist...\n");
+        dprintf(out, "Log processor does not exist...\n");
         return UNKNOWN_ERROR;
     }
 }
 
-status_t StatsService::cmd_print_stats(FILE* out, const Vector<String8>& args) {
+status_t StatsService::cmd_print_stats(int out, const Vector<String8>& args) {
     int argCount = args.size();
     bool proto = false;
     if (!std::strcmp("--proto", args[argCount-1].c_str())) {
@@ -638,13 +622,13 @@
         vector<uint8_t> data;
         statsdStats.dumpStats(&data, false); // does not reset statsdStats.
         for (size_t i = 0; i < data.size(); i ++) {
-            fprintf(out, "%c", data[i]);
+            dprintf(out, "%c", data[i]);
         }
 
     } else {
         vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
         for (const ConfigKey& key : configs) {
-            fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
+            dprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
                     mProcessor->GetMetricsSize(key));
         }
         statsdStats.dumpStats(out);
@@ -652,29 +636,29 @@
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_print_uid_map(FILE* out, const Vector<String8>& args) {
+status_t StatsService::cmd_print_uid_map(int out, const Vector<String8>& args) {
     if (args.size() > 1) {
         string pkg;
         pkg.assign(args[1].c_str(), args[1].size());
         auto uids = mUidMap->getAppUid(pkg);
-        fprintf(out, "%s -> [ ", pkg.c_str());
+        dprintf(out, "%s -> [ ", pkg.c_str());
         for (const auto& uid : uids) {
-            fprintf(out, "%d ", uid);
+            dprintf(out, "%d ", uid);
         }
-        fprintf(out, "]\n");
+        dprintf(out, "]\n");
     } else {
         mUidMap->printUidMap(out);
     }
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_write_data_to_disk(FILE* out) {
-    fprintf(out, "Writing data to disk\n");
+status_t StatsService::cmd_write_data_to_disk(int out) {
+    dprintf(out, "Writing data to disk\n");
     mProcessor->WriteDataToDisk(ADB_DUMP);
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_log_app_breadcrumb(FILE* out, const Vector<String8>& args) {
+status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& args) {
     bool good = false;
     int32_t uid;
     int32_t label;
@@ -695,13 +679,13 @@
             state = atoi(args[3].c_str());
             good = true;
         } else {
-            fprintf(out,
+            dprintf(out,
                     "Selecting a UID for writing AppBreadcrumb can only be done for other UIDs "
-                            "on eng or userdebug builds.\n");
+                    "on eng or userdebug builds.\n");
         }
     }
     if (good) {
-        fprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
+        dprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
         android::util::stats_write(android::util::APP_BREADCRUMB_REPORTED, uid, label, state);
     } else {
         print_cmd_help(out);
@@ -710,46 +694,46 @@
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) {
+status_t StatsService::cmd_print_pulled_metrics(int out, const Vector<String8>& args) {
     int s = atoi(args[1].c_str());
     vector<shared_ptr<LogEvent> > stats;
     if (mPullerManager->Pull(s, getElapsedRealtimeNs(), &stats)) {
         for (const auto& it : stats) {
-            fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
+            dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
         }
-        fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
+        dprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
         return NO_ERROR;
     }
     return UNKNOWN_ERROR;
 }
 
-status_t StatsService::cmd_remove_all_configs(FILE* out) {
-    fprintf(out, "Removing all configs...\n");
+status_t StatsService::cmd_remove_all_configs(int out) {
+    dprintf(out, "Removing all configs...\n");
     VLOG("StatsService::cmd_remove_all_configs was called");
     mConfigManager->RemoveAllConfigs();
     StorageManager::deleteAllFiles(STATS_SERVICE_DIR);
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_dump_memory_info(FILE* out) {
-    fprintf(out, "meminfo not available.\n");
+status_t StatsService::cmd_dump_memory_info(int out) {
+    dprintf(out, "meminfo not available.\n");
     return NO_ERROR;
 }
 
-status_t StatsService::cmd_clear_puller_cache(FILE* out) {
+status_t StatsService::cmd_clear_puller_cache(int out) {
     IPCThreadState* ipc = IPCThreadState::self();
     VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
             ipc->getCallingPid(), ipc->getCallingUid());
     if (checkCallingPermission(String16(kPermissionDump))) {
         int cleared = mPullerManager->ForceClearPullerCache();
-        fprintf(out, "Puller removed %d cached data!\n", cleared);
+        dprintf(out, "Puller removed %d cached data!\n", cleared);
         return NO_ERROR;
     } else {
         return PERMISSION_DENIED;
     }
 }
 
-status_t StatsService::cmd_print_logs(FILE* out, const Vector<String8>& args) {
+status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
     IPCThreadState* ipc = IPCThreadState::self();
     VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", ipc->getCallingPid(),
          ipc->getCallingUid());
@@ -885,6 +869,9 @@
 
 void StatsService::OnLogEvent(LogEvent* event) {
     mProcessor->OnLogEvent(event);
+    if (mShellSubscriber != nullptr) {
+        mShellSubscriber->onLogEvent(*event);
+    }
 }
 
 Status StatsService::getData(int64_t key, const String16& packageName, vector<uint8_t>* output) {
@@ -1005,6 +992,60 @@
     return Status::ok();
 }
 
+hardware::Return<void> StatsService::reportSpeakerImpedance(
+        const SpeakerImpedance& speakerImpedance) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), speakerImpedance);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportHardwareFailed(const HardwareFailed& hardwareFailed) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), hardwareFailed);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportPhysicalDropDetected(
+        const PhysicalDropDetected& physicalDropDetected) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), physicalDropDetected);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportChargeCycles(const ChargeCycles& chargeCycles) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), chargeCycles);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportBatteryHealthSnapshot(
+        const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(),
+                   batteryHealthSnapshotArgs);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportSlowIo(const SlowIo& slowIo) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), slowIo);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportBatteryCausedShutdown(
+        const BatteryCausedShutdown& batteryCausedShutdown) {
+    LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), batteryCausedShutdown);
+    mProcessor->OnLogEvent(&event);
+
+    return hardware::Void();
+}
+
 void StatsService::binderDied(const wp <IBinder>& who) {
     ALOGW("statscompanion service died");
     StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 613f509..1f1d782 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -24,8 +24,11 @@
 #include "external/StatsPullerManager.h"
 #include "logd/LogListener.h"
 #include "packages/UidMap.h"
+#include "shell/ShellSubscriber.h"
 #include "statscompanion_util.h"
 
+#include <android/frameworks/stats/1.0/IStats.h>
+#include <android/frameworks/stats/1.0/types.h>
 #include <android/os/BnStatsManager.h>
 #include <android/os/IStatsCompanionService.h>
 #include <binder/IResultReceiver.h>
@@ -37,6 +40,7 @@
 using namespace android;
 using namespace android::base;
 using namespace android::binder;
+using namespace android::frameworks::stats::V1_0;
 using namespace android::os;
 using namespace std;
 
@@ -44,7 +48,12 @@
 namespace os {
 namespace statsd {
 
-class StatsService : public BnStatsManager, public LogListener, public IBinder::DeathRecipient {
+using android::hardware::Return;
+
+class StatsService : public BnStatsManager,
+                     public LogListener,
+                     public IStats,
+                     public IBinder::DeathRecipient {
 public:
     StatsService(const sp<Looper>& handlerLooper);
     virtual ~StatsService();
@@ -54,7 +63,8 @@
 
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
     virtual status_t dump(int fd, const Vector<String16>& args);
-    virtual status_t command(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
+    virtual status_t command(int inFd, int outFd, int err, Vector<String8>& args,
+                             sp<IResultReceiver> resultReceiver);
 
     virtual Status systemRunning();
     virtual Status statsCompanionReady();
@@ -144,6 +154,44 @@
      */
     virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
 
+    /**
+     * Binder call to get SpeakerImpedance atom.
+     */
+    virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override;
+
+    /**
+     * Binder call to get HardwareFailed atom.
+     */
+    virtual Return<void> reportHardwareFailed(const HardwareFailed& hardwareFailed) override;
+
+    /**
+     * Binder call to get PhysicalDropDetected atom.
+     */
+    virtual Return<void> reportPhysicalDropDetected(
+            const PhysicalDropDetected& physicalDropDetected) override;
+
+    /**
+     * Binder call to get ChargeCyclesReported atom.
+     */
+    virtual Return<void> reportChargeCycles(const ChargeCycles& chargeCycles) override;
+
+    /**
+     * Binder call to get BatteryHealthSnapshot atom.
+     */
+    virtual Return<void> reportBatteryHealthSnapshot(
+            const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) override;
+
+    /**
+     * Binder call to get SlowIo atom.
+     */
+    virtual Return<void> reportSlowIo(const SlowIo& slowIo) override;
+
+    /**
+     * Binder call to get BatteryCausedShutdown atom.
+     */
+    virtual Return<void> reportBatteryCausedShutdown(
+            const BatteryCausedShutdown& batteryCausedShutdown) override;
+
     /** IBinder::DeathRecipient */
     virtual void binderDied(const wp<IBinder>& who) override;
 
@@ -162,73 +210,73 @@
     /**
      * Text or proto output of dumpsys.
      */
-    void dump_impl(FILE* out, bool verbose, bool proto);
+    void dump_impl(int outFd, bool verbose, bool proto);
 
     /**
      * Print usage information for the commands
      */
-    void print_cmd_help(FILE* out);
+    void print_cmd_help(int out);
 
     /**
      * Trigger a broadcast.
      */
-    status_t cmd_trigger_broadcast(FILE* out, Vector<String8>& args);
+    status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args);
 
     /**
      * Handle the config sub-command.
      */
-    status_t cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
+    status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args);
 
     /**
      * Prints some basic stats to std out.
      */
-    status_t cmd_print_stats(FILE* out, const Vector<String8>& args);
+    status_t cmd_print_stats(int outFd, const Vector<String8>& args);
 
     /**
      * Print the event log.
      */
-    status_t cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args);
+    status_t cmd_dump_report(int outFd, int err, const Vector<String8>& args);
 
     /**
      * Print the mapping of uids to package names.
      */
-    status_t cmd_print_uid_map(FILE* out, const Vector<String8>& args);
+    status_t cmd_print_uid_map(int outFd, const Vector<String8>& args);
 
     /**
      * Flush the data to disk.
      */
-    status_t cmd_write_data_to_disk(FILE* out);
+    status_t cmd_write_data_to_disk(int outFd);
 
     /**
      * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling
      * StatsLog.write(APP_BREADCRUMB_REPORTED).
      */
-    status_t cmd_log_app_breadcrumb(FILE* out, const Vector<String8>& args);
+    status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args);
 
     /**
      * Print contents of a pulled metrics source.
      */
-    status_t cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args);
+    status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args);
 
     /**
      * Removes all configs stored on disk and on memory.
      */
-    status_t cmd_remove_all_configs(FILE* out);
+    status_t cmd_remove_all_configs(int outFd);
 
     /*
      * Dump memory usage by statsd.
      */
-    status_t cmd_dump_memory_info(FILE* out);
+    status_t cmd_dump_memory_info(int outFd);
 
     /*
      * Clear all puller cached data
      */
-    status_t cmd_clear_puller_cache(FILE* out);
+    status_t cmd_clear_puller_cache(int outFd);
 
     /**
      * Print all stats logs received to logcat.
      */
-    status_t cmd_print_logs(FILE* out, const Vector<String8>& args);
+    status_t cmd_print_logs(int outFd, const Vector<String8>& args);
 
     /**
      * Adds a configuration after checking permissions and obtaining UID from binder call.
@@ -275,6 +323,8 @@
      */
     bool mEngBuild;
 
+    sp<ShellSubscriber> mShellSubscriber;
+
     FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
     FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
     FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 13ae41d..9d83afd 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -31,6 +31,7 @@
 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";
+import "frameworks/base/core/proto/android/internal/powerprofile.proto";
 
 /**
  * The master atom class. This message defines all of the available
@@ -80,7 +81,8 @@
         BatteryLevelChanged battery_level_changed = 30;
         ChargingStateChanged charging_state_changed = 31;
         PluggedStateChanged plugged_state_changed = 32;
-        // 33 - 34 are available
+        InteractiveStateChanged interactive_state_changed = 33;
+        // 34 is available
         WakeupAlarmOccurred wakeup_alarm_occurred = 35;
         KernelWakeupReported kernel_wakeup_reported = 36;
         WifiLockStateChanged wifi_lock_state_changed = 37;
@@ -136,6 +138,10 @@
         FingerprintAcquired fingerprint_acquired = 87;
         FingerprintAuthenticated fingerprint_authenticated = 88;
         FingerprintErrorOccurred fingerprint_error_occurred = 89;
+        Notification notification = 90;
+        BatteryHealthSnapshot battery_health_snapshot = 91;
+        SlowIo slow_io = 92;
+        BatteryCausedShutdown battery_caused_shutdown = 93;
     }
 
     // Pulled events will start at field 10000.
@@ -170,13 +176,17 @@
         DirectoryUsage directory_usage = 10026;
         AppSize app_size = 10027;
         CategorySize category_size = 10028;
-        android.service.procstats.ProcessStatsSectionProto proc_stats = 10029;
+        ProcStats proc_stats = 10029;
         BatteryVoltage battery_voltage = 10030;
         NumFingerprints num_fingerprints = 10031;
+        DiskIo disk_io = 10032;
+        PowerProfile power_profile = 10033;
+        ProcStats proc_stats_pkg_proc = 10034;
     }
 
-    // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above
-    // 100,000 are reserved for non-AOSP (e.g. OEMs) to use.
+    // DO NOT USE field numbers above 100,000 in AOSP.
+    // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use.
+    // Field numbers 200,000 and above are reserved for future use; do not use them at all.
 }
 
 /**
@@ -197,9 +207,10 @@
 message KeyValuePair {
     optional int32 key = 1;
     oneof value {
-        int64 value_int = 2;
-        string value_str = 3;
-        float value_float = 4;
+        int32 value_int = 2;
+        int64 value_long = 3;
+        string value_str = 4;
+        float value_float = 5;
     }
 }
 
@@ -663,6 +674,20 @@
 }
 
 /**
+ * Logs when the device is interactive, according to the PowerManager Notifier.
+ *
+ * Logged from:
+ *   frameworks/base/services/core/java/com/android/server/power/Notifier.java
+ */
+message InteractiveStateChanged {
+    enum State {
+        OFF = 0;
+        ON = 1;
+    }
+    optional State state = 1;
+}
+
+/**
  * Logs Battery Saver state change.
  *
  * Logged from:
@@ -752,6 +777,9 @@
 
     // Name of the wakeup alarm.
     optional string tag = 2;
+
+    // Name of source package (for historical reasons, since BatteryStats tracked it).
+    optional string package_name = 3;
 }
 
 /**
@@ -1292,6 +1320,68 @@
 }
 
 /**
+ * Log battery health snapshot.
+ *
+ * Resistance, Voltage, Open Circuit Voltage, Temperature, and Charge Level
+ * are snapshotted periodically over 24hrs.
+ */
+message BatteryHealthSnapshot {
+    enum BatterySnapshotType {
+        UNKNOWN = 0;
+        MIN_TEMP = 1;         // Snapshot at min batt temp over 24hrs.
+        MAX_TEMP = 2;         // Snapshot at max batt temp over 24hrs.
+        MIN_RESISTANCE = 3;   // Snapshot at min batt resistance over 24hrs.
+        MAX_RESISTANCE = 4;   // Snapshot at max batt resistance over 24hrs.
+        MIN_VOLTAGE = 5;      // Snapshot at min batt voltage over 24hrs.
+        MAX_VOLTAGE = 6;      // Snapshot at max batt voltage over 24hrs.
+        MIN_CURRENT = 7;      // Snapshot at min batt current over 24hrs.
+        MAX_CURRENT = 8;      // Snapshot at max batt current over 24hrs.
+        MIN_BATT_LEVEL = 9;   // Snapshot at min battery level (SoC) over 24hrs.
+        MAX_BATT_LEVEL = 10;  // Snapshot at max battery level (SoC) over 24hrs.
+        AVG_RESISTANCE = 11;  // Snapshot at average battery resistance over 24hrs.
+    }
+    optional BatterySnapshotType type = 1;
+    // Temperature, in 1/10ths of degree C.
+    optional int32 temperature_deci_celcius = 2;
+    // Voltage Battery Voltage, in microVolts.
+    optional int32 voltage_micro_volt = 3;
+    // Current Battery current, in microAmps.
+    optional int32 current_micro_amps = 4;
+    // OpenCircuitVoltage Battery Open Circuit Voltage, in microVolts.
+    optional int32 open_circuit_micro_volt = 5;
+    // Resistance Battery Resistance, in microOhms.
+    optional int32 resistance_micro_ohm = 6;
+    // Level Battery Level, as % of full.
+    optional int32 level_percent = 7;
+}
+
+/**
+ * Log slow I/O operations on the primary storage.
+ */
+message SlowIo {
+    // Classifications of IO Operations.
+    enum IoOperation {
+        UNKNOWN = 0;
+        READ = 1;
+        WRITE = 2;
+        UNMAP = 3;
+        SYNC = 4;
+    }
+    optional IoOperation operation = 1;
+
+    // The number of slow IO operations of this type over 24 hours.
+    optional int32 count = 2;
+}
+
+/**
+ * Log battery caused shutdown with the last recorded voltage.
+ */
+message BatteryCausedShutdown {
+    // The last recorded battery voltage prior to shutdown.
+    optional int32 last_recorded_micro_volt = 1;
+}
+
+/**
  * Logs the duration of a davey (jank of >=700ms) when it occurs
  *
  * Logged from:
@@ -1890,6 +1980,69 @@
     // The type of error.
     optional Error error = 3;
 }
+
+message Notification {
+
+    // Type of notification event.
+    enum Type {
+        TYPE_UNKNOWN = 0;
+        // Notification became visible to the user.
+        TYPE_OPEN = 1;
+        // Notification became hidden.
+        TYPE_CLOSE = 2;
+        // Notification switched to detail mode.
+        TYPE_DETAIL = 3;
+        // Notification was clicked.
+        TYPE_ACTION = 4;
+        // Notification was dismissed.
+        TYPE_DISMISS = 5;
+        // Notification switched to summary mode. The enum value of 14 is to
+        // match that of metrics_constants.
+        TYPE_COLLAPSE = 14;
+    }
+    optional Type type = 1;
+
+    // Package name associated with the notification.
+    optional string package_name = 2;
+
+    // Tag associated with notification.
+    optional string tag = 3;
+
+    // Application-supplied ID associated with the notification.
+    optional int32 id = 4;
+
+    // Index of notification in the notification panel.
+    optional int32 shade_index = 5;
+
+    // The number of notifications in the notification panel.
+    optional int32 shade_count = 6;
+
+    // Importance for the notification.
+    optional int32 importance = 7;
+
+    // ID for the notification channel.
+    optional int32 channel_id = 8;
+
+    // Importance for the notification channel.
+    optional int32 channel_importance = 9;
+
+    // Whether notification was a group summary.
+    optional bool group_summary = 10;
+
+    // Time since notification was created in milliseconds.
+    optional int64 since_create_millis = 11;
+
+    // Time since notification was interrupted in milliseconds.
+    optional int64 since_interruption_millis = 12;
+
+    // Time since notification was updated in milliseconds.
+    optional int64 since_update_millis = 13;
+
+    // Time since notification was visible in milliseconds.
+    optional int64 since_visible_millis = 14;
+}
+
+
 //////////////////////////////////////////////////////////////////////
 // Pulled atoms below this line //
 //////////////////////////////////////////////////////////////////////
@@ -2155,6 +2308,11 @@
 
     // SWAP
     optional int64 swap_in_bytes = 8;
+
+    // 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 = 9;
 }
 
 /*
@@ -2339,7 +2497,7 @@
  * Next tag: 11
  */
 message LooperStats {
-    // Currently not collected and always set to 0.
+    // The uid that made a call to the System Server and caused the message to be enqueued.
     optional int32 uid = 1 [(is_uid) = true];
 
     // Fully qualified class name of the handler target class.
@@ -2468,6 +2626,30 @@
 }
 
 /**
+ * Pulls per uid I/O stats. The stats are cumulative since boot.
+ *
+ * Read/write bytes are I/O events from a storage device
+ * Read/write chars are data requested by read/write syscalls, and can be
+ *   satisfied by caching.
+ *
+ * Pulled from StatsCompanionService, which reads proc/uid_io/stats.
+ */
+message DiskIo {
+    optional int32 uid = 1 [(is_uid) = true];
+    optional int64 fg_chars_read = 2;
+    optional int64 fg_chars_write = 3;
+    optional int64 fg_bytes_read = 4;
+    optional int64 fg_bytes_write = 5;
+    optional int64 bg_chars_read = 6;
+    optional int64 bg_chars_write = 7;
+    optional int64 bg_bytes_read = 8;
+    optional int64 bg_bytes_write = 9;
+    optional int64 fg_fsync = 10;
+    optional int64 bg_fsync= 11;
+}
+
+
+/**
  * Pulls the number of fingerprints for each user.
  *
  * Pulled from StatsCompanionService, which queries FingerprintManager.
@@ -2479,3 +2661,18 @@
     // Number of fingerprints registered to that user.
     optional int32 num_fingerprints = 2;
 }
+
+/**
+ * Pulled from ProcessStatsService.java
+ */
+message ProcStats {
+    optional android.service.procstats.ProcessStatsSectionProto proc_stats_section = 1;
+}
+
+/**
+ * power_profile.xml and other constants for power model calculations.
+ * Pulled from PowerProfile.java
+ */
+message PowerProfile {
+    optional com.android.internal.os.PowerProfileProto power_profile_proto = 1;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
index d953f50..3eb05a9 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
@@ -36,8 +36,6 @@
 namespace os {
 namespace statsd {
 
-const int kLogMsgHeaderSize = 28;
-
 // The reading and parsing are implemented in Java. It is not difficult to port over. But for now
 // let StatsCompanionService handle that and send the data back.
 StatsCompanionServicePuller::StatsCompanionServicePuller(int tagId) : StatsPuller(tagId) {
@@ -56,20 +54,12 @@
         vector<StatsLogEventWrapper> returned_value;
         Status status = statsCompanionServiceCopy->pullData(mTagId, &returned_value);
         if (!status.isOk()) {
-            ALOGW("error pulling for %d", mTagId);
+            ALOGW("StatsCompanionServicePuller::pull failed for %d", mTagId);
             return false;
         }
         data->clear();
-        int32_t timestampSec = getWallClockSec();
         for (const StatsLogEventWrapper& it : returned_value) {
-            log_msg tmp;
-            tmp.entry_v1.len = it.bytes.size();
-            // Manually set the header size to 28 bytes to match the pushed log events.
-            tmp.entry.hdr_size = kLogMsgHeaderSize;
-            tmp.entry_v1.sec = timestampSec;
-            // And set the received bytes starting after the 28 bytes reserved for header.
-            std::copy(it.bytes.begin(), it.bytes.end(), tmp.buf + kLogMsgHeaderSize);
-            data->push_back(make_shared<LogEvent>(tmp));
+            data->push_back(make_shared<LogEvent>(it));
         }
         VLOG("StatsCompanionServicePuller::pull succeeded for %d", mTagId);
         return true;
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index c23d65e..dab64ca 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -163,13 +163,10 @@
           new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}},
         // battery_voltage
         {android::util::BATTERY_VOLTAGE,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)}},
+         {{}, {}, 1 * NS_PER_SEC, new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)}},
         // process_memory_state
         {android::util::PROCESS_MEMORY_STATE,
-         {{4, 5, 6, 7, 8},
+         {{4, 5, 6, 7, 8, 9},
           {2, 3},
           1 * NS_PER_SEC,
           new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
@@ -195,35 +192,38 @@
           new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
         // Disk Stats
         {android::util::DISK_STATS,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::DISK_STATS)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DISK_STATS)}},
         // Directory usage
         {android::util::DIRECTORY_USAGE,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
         // Size of app's code, data, and cache
         {android::util::APP_SIZE,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::APP_SIZE)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::APP_SIZE)}},
         // Size of specific categories of files. Eg. Music.
         {android::util::CATEGORY_SIZE,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}},
         // Number of fingerprints registered to each user.
         {android::util::NUM_FINGERPRINTS,
          {{},
           {},
           1 * NS_PER_SEC,
           new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS)}},
-        };
+        // 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)}},
+};
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
 }
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 33f3917..bf0bfec 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -400,36 +400,35 @@
     return string(timeBuffer);
 }
 
-void StatsdStats::dumpStats(FILE* out) const {
+void StatsdStats::dumpStats(int out) const {
     lock_guard<std::mutex> lock(mLock);
     time_t t = mStartTimeSec;
     struct tm* tm = localtime(&t);
     char timeBuffer[80];
     strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
-    fprintf(out, "Stats collection start second: %s\n", timeBuffer);
-    fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
+    dprintf(out, "Stats collection start second: %s\n", timeBuffer);
+    dprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
     for (const auto& configStats : mIceBox) {
-        fprintf(out,
+        dprintf(out,
                 "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
                 "#matcher=%d, #alert=%d,  valid=%d\n",
                 configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
                 configStats->deletion_time_sec, configStats->reset_time_sec,
-                configStats->metric_count,
-                configStats->condition_count, configStats->matcher_count, configStats->alert_count,
-                configStats->is_valid);
+                configStats->metric_count, configStats->condition_count, configStats->matcher_count,
+                configStats->alert_count, configStats->is_valid);
 
         for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
-            fprintf(out, "\tbroadcast time: %d\n", broadcastTime);
+            dprintf(out, "\tbroadcast time: %d\n", broadcastTime);
         }
 
         for (const auto& dataDropTime : configStats->data_drop_time_sec) {
-            fprintf(out, "\tdata drop time: %d\n", dataDropTime);
+            dprintf(out, "\tdata drop time: %d\n", dataDropTime);
         }
     }
-    fprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
+    dprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
     for (auto& pair : mConfigStats) {
         auto& configStats = pair.second;
-        fprintf(out,
+        dprintf(out,
                 "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
                 "#matcher=%d, #alert=%d,  valid=%d\n",
                 configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
@@ -437,81 +436,81 @@
                 configStats->condition_count, configStats->matcher_count, configStats->alert_count,
                 configStats->is_valid);
         for (const auto& annotation : configStats->annotations) {
-            fprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
+            dprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
                     annotation.second);
         }
 
         for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
-            fprintf(out, "\tbroadcast time: %s(%lld)\n",
-                    buildTimeString(broadcastTime).c_str(), (long long)broadcastTime);
+            dprintf(out, "\tbroadcast time: %s(%lld)\n", buildTimeString(broadcastTime).c_str(),
+                    (long long)broadcastTime);
         }
 
         for (const auto& dataDropTime : configStats->data_drop_time_sec) {
-            fprintf(out, "\tdata drop time: %s(%lld)\n",
-                    buildTimeString(dataDropTime).c_str(), (long long)dataDropTime);
+            dprintf(out, "\tdata drop time: %s(%lld)\n", buildTimeString(dataDropTime).c_str(),
+                    (long long)dataDropTime);
         }
 
         for (const auto& dump : configStats->dump_report_stats) {
-            fprintf(out, "\tdump report time: %s(%lld) bytes: %lld\n",
+            dprintf(out, "\tdump report time: %s(%lld) bytes: %lld\n",
                     buildTimeString(dump.first).c_str(), (long long)dump.first,
                     (long long)dump.second);
         }
 
         for (const auto& stats : pair.second->matcher_stats) {
-            fprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
+            dprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
         }
 
         for (const auto& stats : pair.second->condition_stats) {
-            fprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
+            dprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
                     stats.second);
         }
 
         for (const auto& stats : pair.second->condition_stats) {
-            fprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
+            dprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
                     stats.second);
         }
 
         for (const auto& stats : pair.second->alert_stats) {
-            fprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
+            dprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
         }
     }
-    fprintf(out, "********Disk Usage stats***********\n");
+    dprintf(out, "********Disk Usage stats***********\n");
     StorageManager::printStats(out);
-    fprintf(out, "********Pushed Atom stats***********\n");
+    dprintf(out, "********Pushed Atom stats***********\n");
     const size_t atomCounts = mPushedAtomStats.size();
     for (size_t i = 2; i < atomCounts; i++) {
         if (mPushedAtomStats[i] > 0) {
-            fprintf(out, "Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]);
+            dprintf(out, "Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]);
         }
     }
 
-    fprintf(out, "********Pulled Atom stats***********\n");
+    dprintf(out, "********Pulled Atom stats***********\n");
     for (const auto& pair : mPulledAtomStats) {
-        fprintf(out, "Atom %d->%ld, %ld, %ld\n", (int)pair.first, (long)pair.second.totalPull,
+        dprintf(out, "Atom %d->%ld, %ld, %ld\n", (int)pair.first, (long)pair.second.totalPull,
                 (long)pair.second.totalPullFromCache, (long)pair.second.minPullIntervalSec);
     }
 
     if (mAnomalyAlarmRegisteredStats > 0) {
-        fprintf(out, "********AnomalyAlarmStats stats***********\n");
-        fprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
+        dprintf(out, "********AnomalyAlarmStats stats***********\n");
+        dprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
     }
 
     if (mPeriodicAlarmRegisteredStats > 0) {
-        fprintf(out, "********SubscriberAlarmStats stats***********\n");
-        fprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
+        dprintf(out, "********SubscriberAlarmStats stats***********\n");
+        dprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
     }
 
-    fprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
+    dprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
             mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps,
             mUidMapStats.dropped_changes);
 
     for (const auto& restart : mSystemServerRestartSec) {
-        fprintf(out, "System server restarts at %s(%lld)\n",
-            buildTimeString(restart).c_str(), (long long)restart);
+        dprintf(out, "System server restarts at %s(%lld)\n", buildTimeString(restart).c_str(),
+                (long long)restart);
     }
 
     for (const auto& loss : mLogLossStats) {
-        fprintf(out, "Log loss: %lld (wall clock sec) - %d (count)\n", (long long)loss.first,
+        dprintf(out, "Log loss: %lld (wall clock sec) - %d (count)\n", (long long)loss.first,
                 loss.second);
     }
 }
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index b5156da..a8188c8 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -156,7 +156,7 @@
      * Report a config has been removed.
      */
     void noteConfigRemoved(const ConfigKey& key);
-   /**
+    /**
      * Report a config has been reset when ttl expires.
      */
     void noteConfigReset(const ConfigKey& key);
@@ -202,7 +202,6 @@
      */
     void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
 
-
     /**
      * Report the max size of output tuple of dimension in condition across dimensions in what.
      *
@@ -272,8 +271,8 @@
     void notePullFromCache(int pullAtomId);
 
     /*
-    * Records when system server restarts.
-    */
+     * Records when system server restarts.
+     */
     void noteSystemServerRestart(int32_t timeSec);
 
     /**
@@ -296,9 +295,9 @@
     void dumpStats(std::vector<uint8_t>* buffer, bool reset);
 
     /**
-     * Output statsd stats in human readable format to [out] file.
+     * Output statsd stats in human readable format to [out] file descriptor.
      */
-    void dumpStats(FILE* out) const;
+    void dumpStats(int outFd) const;
 
     typedef struct {
         long totalPull;
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index cf04ee3..4bbcfd5 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -41,6 +41,44 @@
     }
 }
 
+LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper) {
+    mTagId = statsLogEventWrapper.getTagId();
+    mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs();
+    mElapsedTimestampNs = statsLogEventWrapper.getElapsedRealTimeNs();
+    mLogUid = 0;
+    for (int i = 0; i < (int)statsLogEventWrapper.getElements().size(); i++) {
+        Field field(statsLogEventWrapper.getTagId(), getSimpleField(i + 1));
+        switch (statsLogEventWrapper.getElements()[i].type) {
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::INT:
+                mValues.push_back(
+                        FieldValue(field, Value(statsLogEventWrapper.getElements()[i].int_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::LONG:
+                mValues.push_back(
+                        FieldValue(field, Value(statsLogEventWrapper.getElements()[i].long_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::FLOAT:
+                mValues.push_back(FieldValue(
+                        field, Value(statsLogEventWrapper.getElements()[i].float_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::DOUBLE:
+                mValues.push_back(FieldValue(
+                        field, Value(statsLogEventWrapper.getElements()[i].double_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STRING:
+                mValues.push_back(
+                        FieldValue(field, Value(statsLogEventWrapper.getElements()[i].str_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STORAGE:
+                mValues.push_back(FieldValue(
+                        field, Value(statsLogEventWrapper.getElements()[i].storage_value)));
+                break;
+            default:
+                break;
+        }
+    }
+}
+
 LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) {
     mLogdTimestampNs = wallClockTimestampNs;
     mTagId = tagId;
@@ -54,7 +92,8 @@
 
 LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
                    int32_t uid,
-                   const std::map<int32_t, int64_t>& int_map,
+                   const std::map<int32_t, int32_t>& int_map,
+                   const std::map<int32_t, int64_t>& long_map,
                    const std::map<int32_t, std::string>& string_map,
                    const std::map<int32_t, float>& float_map) {
     mLogdTimestampNs = wallClockTimestampNs;
@@ -75,7 +114,7 @@
         pos[1]++;
     }
 
-    for (const auto&itr : string_map) {
+    for (const auto&itr : long_map) {
         pos[2] = 1;
         mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
         pos[2] = 3;
@@ -84,7 +123,7 @@
         pos[1]++;
     }
 
-    for (const auto&itr : float_map) {
+    for (const auto&itr : string_map) {
         pos[2] = 1;
         mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
         pos[2] = 4;
@@ -92,12 +131,142 @@
         mValues.back().mField.decorateLastPos(2);
         pos[1]++;
     }
+
+    for (const auto&itr : float_map) {
+        pos[2] = 1;
+        mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
+        pos[2] = 5;
+        mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
+        mValues.back().mField.decorateLastPos(2);
+        pos[1]++;
+    }
     if (!mValues.empty()) {
         mValues.back().mField.decorateLastPos(1);
         mValues.at(mValues.size() - 2).mField.decorateLastPos(1);
     }
 }
 
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const SpeakerImpedance& speakerImpedance) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::SPEAKER_IMPEDANCE_REPORTED;
+
+    mValues.push_back(
+            FieldValue(Field(mTagId, getSimpleField(1)), Value(speakerImpedance.speakerLocation)));
+    mValues.push_back(
+            FieldValue(Field(mTagId, getSimpleField(2)), Value(speakerImpedance.milliOhms)));
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const HardwareFailed& hardwareFailed) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::HARDWARE_FAILED;
+
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+                                 Value(int32_t(hardwareFailed.hardwareType))));
+    mValues.push_back(
+            FieldValue(Field(mTagId, getSimpleField(2)), Value(hardwareFailed.hardwareLocation)));
+    mValues.push_back(
+            FieldValue(Field(mTagId, getSimpleField(3)), Value(int32_t(hardwareFailed.errorCode))));
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const PhysicalDropDetected& physicalDropDetected) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::PHYSICAL_DROP_DETECTED;
+
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+                                 Value(int32_t(physicalDropDetected.confidencePctg))));
+    mValues.push_back(
+            FieldValue(Field(mTagId, getSimpleField(2)), Value(physicalDropDetected.accelPeak)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
+                                 Value(physicalDropDetected.freefallDuration)));
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const ChargeCycles& chargeCycles) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::CHARGE_CYCLES_REPORTED;
+
+    for (size_t i = 0; i < chargeCycles.cycleBucket.size(); i++) {
+        mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 1)),
+                                     Value(chargeCycles.cycleBucket[i])));
+    }
+
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::BATTERY_HEALTH_SNAPSHOT;
+
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+                                 Value(int32_t(batteryHealthSnapshotArgs.type))));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)),
+                                 Value(batteryHealthSnapshotArgs.temperatureDeciC)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
+                                 Value(batteryHealthSnapshotArgs.voltageMicroV)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)),
+                                 Value(batteryHealthSnapshotArgs.currentMicroA)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(5)),
+                                 Value(batteryHealthSnapshotArgs.openCircuitVoltageMicroV)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)),
+                                 Value(batteryHealthSnapshotArgs.resistanceMicroOhm)));
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)),
+                                 Value(batteryHealthSnapshotArgs.levelPercent)));
+
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, const SlowIo& slowIo) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::SLOW_IO;
+
+    int pos[] = {1};
+    mValues.push_back(
+            FieldValue(Field(mTagId, getSimpleField(1)), Value(int32_t(slowIo.operation))));
+    pos[0]++;
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(slowIo.count)));
+
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                   const BatteryCausedShutdown& batteryCausedShutdown) {
+    mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
+    mTagId = android::util::BATTERY_CAUSED_SHUTDOWN;
+
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+                                 Value(batteryCausedShutdown.voltageMicroV)));
+
+    if (!mValues.empty()) {
+        mValues.back().mField.decorateLastPos(1);
+    }
+}
+
 LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) {
     mLogdTimestampNs = timestampNs;
     mTagId = tagId;
@@ -175,9 +344,8 @@
     return false;
 }
 
-
-
-bool LogEvent::writeKeyValuePairs(const std::map<int32_t, int64_t>& int_map,
+bool LogEvent::writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
+                                  const std::map<int32_t, int64_t>& long_map,
                                   const std::map<int32_t, std::string>& string_map,
                                   const std::map<int32_t, float>& float_map) {
     if (mContext) {
@@ -195,6 +363,17 @@
              }
          }
 
+         for (const auto& itr : long_map) {
+             if (android_log_write_list_begin(mContext) < 0) {
+                return false;
+             }
+             write(itr.first);
+             write(itr.second);
+             if (android_log_write_list_end(mContext) < 0) {
+                return false;
+             }
+         }
+
          for (const auto& itr : string_map) {
              if (android_log_write_list_begin(mContext) < 0) {
                 return false;
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 2ee6bdf..c7e2a8c 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -18,6 +18,8 @@
 
 #include "FieldValue.h"
 
+#include <android/frameworks/stats/1.0/types.h>
+#include <android/os/StatsLogEventWrapper.h>
 #include <android/util/ProtoOutputStream.h>
 #include <log/log_event_list.h>
 #include <log/log_read.h>
@@ -27,6 +29,8 @@
 #include <string>
 #include <vector>
 
+using namespace android::frameworks::stats::V1_0;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -61,6 +65,8 @@
      */
     explicit LogEvent(log_msg& msg);
 
+    explicit LogEvent(const StatsLogEventWrapper& statsLogEventWrapper);
+
     /**
      * Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
      */
@@ -74,10 +80,32 @@
      */
     explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
                       int32_t uid,
-                      const std::map<int32_t, int64_t>& int_map,
+                      const std::map<int32_t, int32_t>& int_map,
+                      const std::map<int32_t, int64_t>& long_map,
                       const std::map<int32_t, std::string>& string_map,
                       const std::map<int32_t, float>& float_map);
 
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const SpeakerImpedance& speakerImpedance);
+
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const HardwareFailed& hardwareFailed);
+
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const PhysicalDropDetected& physicalDropDetected);
+
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const ChargeCycles& chargeCycles);
+
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs);
+
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const SlowIo& slowIo);
+
+    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+                      const BatteryCausedShutdown& batteryCausedShutdown);
+
     ~LogEvent();
 
     /**
@@ -119,7 +147,8 @@
     bool write(float value);
     bool write(const std::vector<AttributionNodeInternal>& nodes);
     bool write(const AttributionNodeInternal& node);
-    bool writeKeyValuePairs(const std::map<int32_t, int64_t>& int_map,
+    bool writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
+                            const std::map<int32_t, int64_t>& long_map,
                             const std::map<int32_t, std::string>& string_map,
                             const std::map<int32_t, float>& float_map);
 
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 9002f07..a5dac08 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -25,6 +25,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <binder/Status.h>
+#include <hidl/HidlTransportSupport.h>
 #include <utils/Looper.h>
 #include <utils/StrongPointer.h>
 
@@ -56,12 +57,21 @@
     ps->giveThreadPoolName();
     IPCThreadState::self()->disableBackgroundScheduling(true);
 
+    ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
+
     // Create the service
     sp<StatsService> service = new StatsService(looper);
     if (defaultServiceManager()->addService(String16("stats"), service) != 0) {
-        ALOGE("Failed to add service");
+        ALOGE("Failed to add service as AIDL service");
         return -1;
     }
+
+    auto ret = service->registerAsService();
+    if (ret != ::android::OK) {
+        ALOGE("Failed to add service as HIDL service");
+        return 1; // or handle error
+    }
+
     service->sayHiToStatsCompanion();
 
     service->Startup();
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 9d9e5be..dd3402d 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -781,7 +781,7 @@
         if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
             for (const auto& condIt : whatIt->second) {
                 const bool cond = dimensionKeysInCondition.find(condIt.first) !=
-                        dimensionKeysInCondition.end();
+                        dimensionKeysInCondition.end() && condition;
                 handleStartEvent(MetricDimensionKey(dimensionInWhat, condIt.first),
                     conditionKey, cond, event);
                 dimensionKeysInCondition.erase(condIt.first);
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index be94725..37a0067 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -386,12 +386,12 @@
     StatsdStats::getInstance().setUidMapChanges(mChanges.size());
 }
 
-void UidMap::printUidMap(FILE* out) const {
+void UidMap::printUidMap(int out) const {
     lock_guard<mutex> lock(mMutex);
 
     for (const auto& kv : mMap) {
         if (!kv.second.deleted) {
-            fprintf(out, "%s, v%" PRId64 " (%i)\n", kv.first.second.c_str(), kv.second.versionCode,
+            dprintf(out, "%s, v%" PRId64 " (%i)\n", kv.first.second.c_str(), kv.second.versionCode,
                     kv.first.first);
         }
     }
@@ -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/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 91f2030..4598369 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -103,7 +103,7 @@
 
     // Helper for debugging contents of this uid map. Can be triggered with:
     // adb shell cmd stats print-uid-map
-    void printUidMap(FILE* out) const;
+    void printUidMap(int outFd) const;
 
     // Commands for indicating to the map that a producer should be notified if an app is updated.
     // This allows the metric producer to distinguish when the same uid or app represents a
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
new file mode 100644
index 0000000..1306a46
--- /dev/null
+++ b/cmds/statsd/src/shell/ShellSubscriber.cpp
@@ -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.
+ */
+#define DEBUG true  // STOPSHIP if true
+#include "Log.h"
+
+#include "ShellSubscriber.h"
+
+#include "matchers/matcher_util.h"
+
+#include <android-base/file.h>
+
+using android::util::ProtoOutputStream;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+void ShellSubscriber::startNewSubscription(int in, int out, sp<IResultReceiver> resultReceiver) {
+    VLOG("start new shell subscription");
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        if (mResultReceiver != nullptr) {
+            VLOG("Only one shell subscriber is allowed.");
+            return;
+        }
+        mInput = in;
+        mOutput = out;
+        mResultReceiver = resultReceiver;
+        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();
+
+    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();
+    for (const auto& pushed : config.pushed()) {
+        mPushedMatchers.push_back(pushed);
+        VLOG("adding matcher for atom %d", pushed.atom_id());
+    }
+}
+
+void ShellSubscriber::readConfig(int in) {
+    if (in <= 0) {
+        return;
+    }
+
+    while (1) {
+        size_t bufferSize = 0;
+        int result = 0;
+        if ((result = read(in, &bufferSize, sizeof(bufferSize))) == 0) {
+            VLOG("Done reading");
+            break;
+        } else if (result < 0 || result != sizeof(bufferSize)) {
+            ALOGE("Error reading config size");
+            break;
+        }
+
+        vector<uint8_t> buffer(bufferSize);
+        if ((result = read(in, buffer.data(), bufferSize)) > 0 && ((size_t)result) == bufferSize) {
+            ShellSubscription config;
+            if (config.ParseFromArray(buffer.data(), bufferSize)) {
+                updateConfig(config);
+            } else {
+                ALOGE("error parsing the config");
+                break;
+            }
+        } else {
+            VLOG("Error reading the config, returned: %d, expecting %zu", result, bufferSize);
+            break;
+        }
+    }
+}
+
+void ShellSubscriber::cleanUpLocked() {
+    // The file descriptors will be closed by binder.
+    mInput = 0;
+    mOutput = 0;
+    mResultReceiver = nullptr;
+    mPushedMatchers.clear();
+    VLOG("done clean up");
+}
+
+void ShellSubscriber::onLogEvent(const LogEvent& event) {
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    if (mOutput <= 0) {
+        return;
+    }
+
+    for (const auto& matcher : mPushedMatchers) {
+        if (matchesSimple(*mUidMap, matcher, event)) {
+            event.ToProto(mProto);
+            // First write the payload size.
+            size_t bufferSize = mProto.size();
+            write(mOutput, &bufferSize, sizeof(bufferSize));
+
+            // Then write the payload.
+            mProto.flush(mOutput);
+            mProto.clear();
+            break;
+        }
+    }
+}
+
+void ShellSubscriber::binderDied(const wp<IBinder>& who) {
+    {
+        VLOG("Shell exits");
+        std::lock_guard<std::mutex> lock(mMutex);
+        cleanUpLocked();
+    }
+    mShellDied.notify_all();
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h
new file mode 100644
index 0000000..0ace35f
--- /dev/null
+++ b/cmds/statsd/src/shell/ShellSubscriber.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "logd/LogEvent.h"
+
+#include <android/util/ProtoOutputStream.h>
+#include <binder/IResultReceiver.h>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+#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"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Handles atoms subscription via shell cmd.
+ *
+ * A shell subscription lasts *until shell exits*. Unlike config based clients, a shell client
+ * communicates with statsd via file descriptors. They can subscribe pushed and pulled atoms.
+ * The atoms are sent back to the client in real time, as opposed to
+ * keeping the data in memory. Shell clients do not subscribe aggregated metrics, as they are
+ * responsible for doing the aggregation after receiving the atom events.
+ *
+ * Shell client pass ShellSubscription in the proto binary format. Client can update the
+ * subscription by sending a new subscription. The new subscription would replace the old one.
+ * Input data stream format is:
+ *
+ * |size_t|subscription proto|size_t|subscription proto|....
+ *
+ * statsd sends the events back in Atom proto binary format. Each Atom message is preceded
+ * 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|....
+ *
+ * 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){};
+
+    /**
+     * Start a new subscription.
+     */
+    void startNewSubscription(int inFd, int outFd, sp<IResultReceiver> resultReceiver);
+
+    void binderDied(const wp<IBinder>& who);
+
+    void onLogEvent(const LogEvent& event);
+
+private:
+    void readConfig(int in);
+
+    void updateConfig(const ShellSubscription& config);
+
+    void cleanUpLocked();
+
+    sp<UidMap> mUidMap;
+
+    // bool mWritten = false;
+
+    android::util::ProtoOutputStream mProto;
+
+    mutable std::mutex mMutex;
+
+    std::condition_variable mShellDied;  // semaphore for waiting until shell exits.
+
+    int mInput;  // The input file descriptor
+
+    int mOutput;  // The output file descriptor
+
+    sp<IResultReceiver> mResultReceiver;
+
+    std::vector<SimpleAtomMatcher> mPushedMatchers;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/shell/shell_config.proto b/cmds/statsd/src/shell/shell_config.proto
new file mode 100644
index 0000000..516693d
--- /dev/null
+++ b/cmds/statsd/src/shell/shell_config.proto
@@ -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.
+ */
+
+syntax = "proto2";
+
+package android.os.statsd;
+
+option java_package = "com.android.os";
+option java_outer_classname = "ShellConfig";
+
+import "frameworks/base/cmds/statsd/src/statsd_config.proto";
+
+message PulledAtomSubscription {
+    optional int32 atom_id = 1;
+
+    /* gap between two pulls in milliseconds */
+    optional int32 freq_millis = 2;
+}
+
+message ShellSubscription {
+    repeated SimpleAtomMatcher pushed = 1;
+    repeated PulledAtomSubscription pulled = 2;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index a0ab3e4..805e583 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -322,6 +322,11 @@
                 case STRING:
                     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(),
+                                       dim.mValue.storage_value.size());
+                    break;
                 default:
                     break;
             }
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 3ebc8a4..2f19a02 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -392,13 +392,13 @@
     }
 }
 
-void StorageManager::printStats(FILE* out) {
-    printDirStats(out, STATS_SERVICE_DIR);
-    printDirStats(out, STATS_DATA_DIR);
+void StorageManager::printStats(int outFd) {
+    printDirStats(outFd, STATS_SERVICE_DIR);
+    printDirStats(outFd, STATS_DATA_DIR);
 }
 
-void StorageManager::printDirStats(FILE* out, const char* path) {
-    fprintf(out, "Printing stats of %s\n", path);
+void StorageManager::printDirStats(int outFd, const char* path) {
+    dprintf(outFd, "Printing stats of %s\n", path);
     unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
     if (dir == NULL) {
         VLOG("Path %s does not exist", path);
@@ -418,25 +418,22 @@
         int64_t timestamp = result[0];
         int64_t uid = result[1];
         int64_t configID = result[2];
-        fprintf(out, "\t #%d, Last updated: %lld, UID: %d, Config ID: %lld",
-                fileCount + 1,
-                (long long)timestamp,
-                (int)uid,
-                (long long)configID);
+        dprintf(outFd, "\t #%d, Last updated: %lld, UID: %d, Config ID: %lld", fileCount + 1,
+                (long long)timestamp, (int)uid, (long long)configID);
         string file_name = getFilePath(path, timestamp, uid, configID);
         ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
         if (file.is_open()) {
             file.seekg(0, ios::end);
             int fileSize = file.tellg();
             file.close();
-            fprintf(out, ", File Size: %d bytes", fileSize);
+            dprintf(outFd, ", File Size: %d bytes", fileSize);
             totalFileSize += fileSize;
         }
-        fprintf(out, "\n");
+        dprintf(outFd, "\n");
         fileCount++;
     }
-    fprintf(out, "\tTotal number of files: %d, Total size of files: %d bytes.\n",
-            fileCount, totalFileSize);
+    dprintf(outFd, "\tTotal number of files: %d, Total size of files: %d bytes.\n", fileCount,
+            totalFileSize);
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
index 4840f3c..8fbc89e 100644
--- a/cmds/statsd/src/storage/StorageManager.h
+++ b/cmds/statsd/src/storage/StorageManager.h
@@ -100,13 +100,13 @@
     /**
      * Prints disk usage statistics related to statsd.
      */
-    static void printStats(FILE* out);
+    static void printStats(int out);
 
 private:
     /**
      * Prints disk usage statistics about a directory related to statsd.
      */
-    static void printDirStats(FILE* out, const char* path);
+    static void printDirStats(int out, const char* path);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 6e3b04c..ced65f2 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -91,12 +91,16 @@
 
 TEST(LogEventTest, TestKeyValuePairsAtomParsing) {
     LogEvent event1(83, 2000);
-    std::map<int32_t, int64_t> int_map;
+    std::map<int32_t, int32_t> int_map;
+    std::map<int32_t, int64_t> long_map;
     std::map<int32_t, std::string> string_map;
     std::map<int32_t, float> float_map;
 
-    int_map[11] = 123L;
-    int_map[22] = 345L;
+    int_map[11] = 123;
+    int_map[22] = 345;
+
+    long_map[33] = 678L;
+    long_map[44] = 890L;
 
     string_map[1] = "test2";
     string_map[2] = "test1";
@@ -104,12 +108,15 @@
     float_map[111] = 2.2f;
     float_map[222] = 1.1f;
 
-    EXPECT_TRUE(event1.writeKeyValuePairs(int_map, string_map, float_map));
+    EXPECT_TRUE(event1.writeKeyValuePairs(int_map,
+                                          long_map,
+                                          string_map,
+                                          float_map));
     event1.init();
 
     EXPECT_EQ(83, event1.GetTagId());
     const auto& items = event1.getValues();
-    EXPECT_EQ((size_t)12, items.size());
+    EXPECT_EQ((size_t)16, items.size());
 
     const FieldValue& item0 = event1.getValues()[0];
     EXPECT_EQ(0x2010101, item0.mField.getField());
@@ -118,8 +125,8 @@
 
     const FieldValue& item1 = event1.getValues()[1];
     EXPECT_EQ(0x2010182, item1.mField.getField());
-    EXPECT_EQ(Type::LONG, item1.mValue.getType());
-    EXPECT_EQ(123L, item1.mValue.long_value);
+    EXPECT_EQ(Type::INT, item1.mValue.getType());
+    EXPECT_EQ(123, item1.mValue.int_value);
 
     const FieldValue& item2 = event1.getValues()[2];
     EXPECT_EQ(0x2010201, item2.mField.getField());
@@ -128,48 +135,68 @@
 
     const FieldValue& item3 = event1.getValues()[3];
     EXPECT_EQ(0x2010282, item3.mField.getField());
-    EXPECT_EQ(Type::LONG, item3.mValue.getType());
-    EXPECT_EQ(345L, item3.mValue.long_value);
+    EXPECT_EQ(Type::INT, item3.mValue.getType());
+    EXPECT_EQ(345, item3.mValue.int_value);
 
     const FieldValue& item4 = event1.getValues()[4];
     EXPECT_EQ(0x2010301, item4.mField.getField());
     EXPECT_EQ(Type::INT, item4.mValue.getType());
-    EXPECT_EQ(1, item4.mValue.int_value);
+    EXPECT_EQ(33, item4.mValue.int_value);
 
     const FieldValue& item5 = event1.getValues()[5];
-    EXPECT_EQ(0x2010383, item5.mField.getField());
-    EXPECT_EQ(Type::STRING, item5.mValue.getType());
-    EXPECT_EQ("test2", item5.mValue.str_value);
+    EXPECT_EQ(0x2010382, item5.mField.getField());
+    EXPECT_EQ(Type::LONG, item5.mValue.getType());
+    EXPECT_EQ(678L, item5.mValue.int_value);
 
     const FieldValue& item6 = event1.getValues()[6];
     EXPECT_EQ(0x2010401, item6.mField.getField());
     EXPECT_EQ(Type::INT, item6.mValue.getType());
-    EXPECT_EQ(2, item6.mValue.int_value);
+    EXPECT_EQ(44, item6.mValue.int_value);
 
     const FieldValue& item7 = event1.getValues()[7];
-    EXPECT_EQ(0x2010483, item7.mField.getField());
-    EXPECT_EQ(Type::STRING, item7.mValue.getType());
-    EXPECT_EQ("test1", item7.mValue.str_value);
+    EXPECT_EQ(0x2010482, item7.mField.getField());
+    EXPECT_EQ(Type::LONG, item7.mValue.getType());
+    EXPECT_EQ(890L, item7.mValue.int_value);
 
     const FieldValue& item8 = event1.getValues()[8];
     EXPECT_EQ(0x2010501, item8.mField.getField());
     EXPECT_EQ(Type::INT, item8.mValue.getType());
-    EXPECT_EQ(111, item8.mValue.int_value);
+    EXPECT_EQ(1, item8.mValue.int_value);
 
     const FieldValue& item9 = event1.getValues()[9];
-    EXPECT_EQ(0x2010584, item9.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item9.mValue.getType());
-    EXPECT_EQ(2.2f, item9.mValue.float_value);
+    EXPECT_EQ(0x2010583, item9.mField.getField());
+    EXPECT_EQ(Type::STRING, item9.mValue.getType());
+    EXPECT_EQ("test2", item9.mValue.str_value);
 
     const FieldValue& item10 = event1.getValues()[10];
-    EXPECT_EQ(0x2018601, item10.mField.getField());
+    EXPECT_EQ(0x2010601, item10.mField.getField());
     EXPECT_EQ(Type::INT, item10.mValue.getType());
-    EXPECT_EQ(222, item10.mValue.int_value);
+    EXPECT_EQ(2, item10.mValue.int_value);
 
     const FieldValue& item11 = event1.getValues()[11];
-    EXPECT_EQ(0x2018684, item11.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item11.mValue.getType());
-    EXPECT_EQ(1.1f, item11.mValue.float_value);
+    EXPECT_EQ(0x2010683, item11.mField.getField());
+    EXPECT_EQ(Type::STRING, item11.mValue.getType());
+    EXPECT_EQ("test1", item11.mValue.str_value);
+
+    const FieldValue& item12 = event1.getValues()[12];
+    EXPECT_EQ(0x2010701, item12.mField.getField());
+    EXPECT_EQ(Type::INT, item12.mValue.getType());
+    EXPECT_EQ(111, item12.mValue.int_value);
+
+    const FieldValue& item13 = event1.getValues()[13];
+    EXPECT_EQ(0x2010784, item13.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item13.mValue.getType());
+    EXPECT_EQ(2.2f, item13.mValue.float_value);
+
+    const FieldValue& item14 = event1.getValues()[14];
+    EXPECT_EQ(0x2018801, item14.mField.getField());
+    EXPECT_EQ(Type::INT, item14.mValue.getType());
+    EXPECT_EQ(222, item14.mValue.int_value);
+
+    const FieldValue& item15 = event1.getValues()[15];
+    EXPECT_EQ(0x2018884, item15.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item15.mValue.getType());
+    EXPECT_EQ(1.1f, item15.mValue.float_value);
 }
 
 TEST(LogEventTest, TestLogParsing2) {
@@ -242,12 +269,16 @@
 }
 
 TEST(LogEventTest, TestKeyValuePairsEvent) {
-    std::map<int32_t, int64_t> int_map;
+    std::map<int32_t, int32_t> int_map;
+    std::map<int32_t, int64_t> long_map;
     std::map<int32_t, std::string> string_map;
     std::map<int32_t, float> float_map;
 
-    int_map[11] = 123L;
-    int_map[22] = 345L;
+    int_map[11] = 123;
+    int_map[22] = 345;
+
+    long_map[33] = 678L;
+    long_map[44] = 890L;
 
     string_map[1] = "test2";
     string_map[2] = "test1";
@@ -255,7 +286,7 @@
     float_map[111] = 2.2f;
     float_map[222] = 1.1f;
 
-    LogEvent event1(83, 2000, 2001, 10001, int_map, string_map, float_map);
+    LogEvent event1(83, 2000, 2001, 10001, int_map, long_map, string_map, float_map);
     event1.init();
 
     EXPECT_EQ(83, event1.GetTagId());
@@ -263,7 +294,7 @@
     EXPECT_EQ((int64_t)2001, event1.GetElapsedTimestampNs());
 
     const auto& items = event1.getValues();
-    EXPECT_EQ((size_t)13, items.size());
+    EXPECT_EQ((size_t)17, items.size());
 
     const FieldValue& item0 = event1.getValues()[0];
     EXPECT_EQ(0x00010000, item0.mField.getField());
@@ -277,8 +308,8 @@
 
     const FieldValue& item2 = event1.getValues()[2];
     EXPECT_EQ(0x2020182, item2.mField.getField());
-    EXPECT_EQ(Type::LONG, item2.mValue.getType());
-    EXPECT_EQ(123L, item2.mValue.long_value);
+    EXPECT_EQ(Type::INT, item2.mValue.getType());
+    EXPECT_EQ(123, item2.mValue.int_value);
 
     const FieldValue& item3 = event1.getValues()[3];
     EXPECT_EQ(0x2020201, item3.mField.getField());
@@ -287,48 +318,68 @@
 
     const FieldValue& item4 = event1.getValues()[4];
     EXPECT_EQ(0x2020282, item4.mField.getField());
-    EXPECT_EQ(Type::LONG, item4.mValue.getType());
-    EXPECT_EQ(345L, item4.mValue.long_value);
+    EXPECT_EQ(Type::INT, item4.mValue.getType());
+    EXPECT_EQ(345, item4.mValue.int_value);
 
     const FieldValue& item5 = event1.getValues()[5];
     EXPECT_EQ(0x2020301, item5.mField.getField());
     EXPECT_EQ(Type::INT, item5.mValue.getType());
-    EXPECT_EQ(1, item5.mValue.int_value);
+    EXPECT_EQ(33, item5.mValue.int_value);
 
     const FieldValue& item6 = event1.getValues()[6];
     EXPECT_EQ(0x2020383, item6.mField.getField());
-    EXPECT_EQ(Type::STRING, item6.mValue.getType());
-    EXPECT_EQ("test2", item6.mValue.str_value);
+    EXPECT_EQ(Type::LONG, item6.mValue.getType());
+    EXPECT_EQ(678L, item6.mValue.long_value);
 
     const FieldValue& item7 = event1.getValues()[7];
     EXPECT_EQ(0x2020401, item7.mField.getField());
     EXPECT_EQ(Type::INT, item7.mValue.getType());
-    EXPECT_EQ(2, item7.mValue.int_value);
+    EXPECT_EQ(44, item7.mValue.int_value);
 
     const FieldValue& item8 = event1.getValues()[8];
     EXPECT_EQ(0x2020483, item8.mField.getField());
-    EXPECT_EQ(Type::STRING, item8.mValue.getType());
-    EXPECT_EQ("test1", item8.mValue.str_value);
+    EXPECT_EQ(Type::LONG, item8.mValue.getType());
+    EXPECT_EQ(890L, item8.mValue.long_value);
 
     const FieldValue& item9 = event1.getValues()[9];
     EXPECT_EQ(0x2020501, item9.mField.getField());
     EXPECT_EQ(Type::INT, item9.mValue.getType());
-    EXPECT_EQ(111, item9.mValue.int_value);
+    EXPECT_EQ(1, item9.mValue.int_value);
 
     const FieldValue& item10 = event1.getValues()[10];
     EXPECT_EQ(0x2020584, item10.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item10.mValue.getType());
-    EXPECT_EQ(2.2f, item10.mValue.float_value);
+    EXPECT_EQ(Type::STRING, item10.mValue.getType());
+    EXPECT_EQ("test2", item10.mValue.str_value);
 
     const FieldValue& item11 = event1.getValues()[11];
-    EXPECT_EQ(0x2028601, item11.mField.getField());
+    EXPECT_EQ(0x2020601, item11.mField.getField());
     EXPECT_EQ(Type::INT, item11.mValue.getType());
-    EXPECT_EQ(222, item11.mValue.int_value);
+    EXPECT_EQ(2, item11.mValue.int_value);
 
     const FieldValue& item12 = event1.getValues()[12];
-    EXPECT_EQ(0x2028684, item12.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item12.mValue.getType());
-    EXPECT_EQ(1.1f, item12.mValue.float_value);
+    EXPECT_EQ(0x2020684, item12.mField.getField());
+    EXPECT_EQ(Type::STRING, item12.mValue.getType());
+    EXPECT_EQ("test1", item12.mValue.str_value);
+
+    const FieldValue& item13 = event1.getValues()[13];
+    EXPECT_EQ(0x2020701, item13.mField.getField());
+    EXPECT_EQ(Type::INT, item13.mValue.getType());
+    EXPECT_EQ(111, item13.mValue.int_value);
+
+    const FieldValue& item14 = event1.getValues()[14];
+    EXPECT_EQ(0x2020785, item14.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
+    EXPECT_EQ(2.2f, item14.mValue.float_value);
+
+    const FieldValue& item15 = event1.getValues()[15];
+    EXPECT_EQ(0x2028801, item15.mField.getField());
+    EXPECT_EQ(Type::INT, item15.mValue.getType());
+    EXPECT_EQ(222, item15.mValue.int_value);
+
+    const FieldValue& item16 = event1.getValues()[16];
+    EXPECT_EQ(0x2028885, item16.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
+    EXPECT_EQ(1.1f, item16.mValue.float_value);
 }
 
 
@@ -337,4 +388,4 @@
 }  // namespace android
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
\ No newline at end of file
+#endif
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
index f038214..75bd40f 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
@@ -81,6 +81,34 @@
 
 }  // namespace
 
+/*
+ The following test has the following input.
+
+{ 10000000002 10000000002 (8)9999[I], [S], job0[S], 1[I],  }
+{ 10000000010 10000000010 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 1[I],  }
+{ 10000000011 10000000011 (29)1[I],  }
+{ 10000000040 10000000040 (29)2[I],  }
+{ 10000000050 10000000050 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 0[I],  }
+{ 10000000101 10000000101 (8)9999[I], [S], job0[S], 0[I],  }
+{ 10000000102 10000000102 (29)1[I],  }
+{ 10000000200 10000000200 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 1[I],  }
+{ 10000000201 10000000201 (8)9999[I], [S], job2[S], 1[I],  }
+{ 10000000400 10000000400 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadDoc[S], 1[I],  }
+{ 10000000401 10000000401 (7)333[I], App2[S], 222[I], GMSCoreModule1[S], 555[I], GMSCoreModule2[S], ReadEmail[S], 1[I],  }
+{ 10000000450 10000000450 (29)2[I],  }
+{ 10000000500 10000000500 (8)9999[I], [S], job2[S], 0[I],  }
+{ 10000000600 10000000600 (8)8888[I], [S], job2[S], 1[I],  }
+{ 10000000650 10000000650 (29)1[I],  }
+{ 309999999999 309999999999 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadDoc[S], 0[I],  }
+{ 310000000100 310000000100 (29)2[I],  }
+{ 310000000300 310000000300 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 0[I],  }
+{ 310000000600 310000000600 (8)8888[I], [S], job1[S], 1[I],  }
+{ 310000000640 310000000640 (29)1[I],  }
+{ 310000000650 310000000650 (29)2[I],  }
+{ 310000000700 310000000700 (7)333[I], App2[S], 222[I], GMSCoreModule1[S], 555[I], GMSCoreModule2[S], ReadEmail[S], 0[I],  }
+{ 310000000850 310000000850 (8)8888[I], [S], job2[S], 0[I],  }
+{ 310000000900 310000000900 (8)8888[I], [S], job1[S], 0[I],  }
+*/
 TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition) {
     for (const bool hashStringInReport : { true, false }) {
         for (bool isDimensionInConditionSubSetOfConditionTrackerDimension : { true, false }) {
@@ -250,7 +278,7 @@
                     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
                     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
-                    EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201 + bucketSizeNs - 600);
+                    EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201 + bucketSizeNs - 650);
                     EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
                     EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
@@ -269,7 +297,7 @@
                             data.dimensions_in_condition(),
                             android::util::SYNC_STATE_CHANGED, 333, "App2");
                     EXPECT_EQ(data.bucket_info_size(), 2);
-                    EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 401 + bucketSizeNs - 600);
+                    EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 401 + bucketSizeNs - 650);
                     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
                     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
@@ -331,7 +359,7 @@
                     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
                     EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201);
-                    EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 100);
+                    EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 650 + 100);
                     EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
                     EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
@@ -353,7 +381,7 @@
                     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
                     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
-                    EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 110);
+                    EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 650 + 110);
                     EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
                               bucketStartTimeNs + bucketSizeNs);
                     EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
new file mode 100644
index 0000000..b380b03
--- /dev/null
+++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
@@ -0,0 +1,136 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 <unistd.h>
+#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
+#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
+#include "src/shell/ShellSubscriber.h"
+#include "tests/metrics/metrics_test_helper.h"
+
+#include <stdio.h>
+#include <vector>
+
+using namespace android::os::statsd;
+using android::sp;
+using std::vector;
+using testing::NaggyMock;
+
+#ifdef __ANDROID__
+
+class MyResultReceiver : public BnResultReceiver {
+public:
+    Mutex mMutex;
+    Condition mCondition;
+    bool mHaveResult = false;
+    int32_t mResult = 0;
+
+    virtual void send(int32_t resultCode) {
+        AutoMutex _l(mMutex);
+        mResult = resultCode;
+        mHaveResult = true;
+        mCondition.signal();
+    }
+
+    int32_t waitForResult() {
+        AutoMutex _l(mMutex);
+        mCondition.waitRelative(mMutex, 1000000000);
+        return mResult;
+    }
+};
+
+TEST(ShellSubscriberTest, testPushedSubscription) {
+    // set up 2 pipes for read/write config and data
+    int fds_config[2];
+    ASSERT_EQ(0, pipe(fds_config));
+
+    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
+    vector<uint8_t> size_buffer(sizeof(bufferSize));
+    std::memcpy(size_buffer.data(), &bufferSize, sizeof(bufferSize));
+    write(fds_config[1], &bufferSize, sizeof(bufferSize));
+    // then write config itself
+    vector<uint8_t> buffer(bufferSize);
+    config.SerializeToArray(&buffer[0], bufferSize);
+    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<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);
+    });
+    reader.detach();
+
+    // 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 (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();
+
+    // 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);
+
+    // 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;
+    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);
+    EXPECT_EQ(atomBuffer, dataBuffer);
+    close(fds_data[0]);
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index 950a258..455e4bb 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -84,7 +84,8 @@
                     cursor.close();
                 }
                 if (provider != null) {
-                    activityManager.removeContentProviderExternal(providerName, token);
+                    activityManager.removeContentProviderExternalAsUser(providerName, token,
+                            UserHandle.USER_SYSTEM);
                 }
             }
         } catch (RemoteException e) {
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index b683138..be9ccec 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -11067,6 +11067,7 @@
 HPLjava/lang/Long;->valueOf(Ljava/lang/String;I)Ljava/lang/Long;
 HPLjava/lang/Math;->addExact(JJ)J
 HPLjava/lang/Math;->scalb(FI)F
+HPLjava/lang/Object;->wait()V
 HPLjava/lang/StackTraceElement;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
 HPLjava/lang/String;->copyValueOf([C)Ljava/lang/String;
 HPLjava/lang/String;->join(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/String;
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0367d9b..6af34f9 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -867,7 +867,6 @@
 Landroid/os/PowerManager;->isLightDeviceIdleMode()Z
 Landroid/os/PowerManager;->mHandler:Landroid/os/Handler;
 Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager;
-Landroid/os/PowerManager;->setPowerSaveMode(Z)Z
 Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V
 Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V
 Landroid/os/Process;->BLUETOOTH_UID:I
@@ -2076,27 +2075,20 @@
 Lcom/android/internal/telephony/ISub;->getDefaultSubId()I
 Lcom/android/internal/telephony/ISub;->setDefaultDataSubId(I)V
 Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z
-Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCallForSubscriber(I)Z
 Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
 Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->isRadioOn(Ljava/lang/String;)Z
 Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony;
 Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String;
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_answerRingingCall:I
 Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I
 Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I
 Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
-Lcom/android/internal/telephony/ITelephony;->answerRingingCall()V
 Lcom/android/internal/telephony/ITelephony;->call(Ljava/lang/String;Ljava/lang/String;)V
 Lcom/android/internal/telephony/ITelephony;->dial(Ljava/lang/String;)V
 Lcom/android/internal/telephony/ITelephony;->disableDataConnectivity()Z
 Lcom/android/internal/telephony/ITelephony;->disableLocationUpdates()V
 Lcom/android/internal/telephony/ITelephony;->enableDataConnectivity()Z
 Lcom/android/internal/telephony/ITelephony;->enableLocationUpdates()V
-Lcom/android/internal/telephony/ITelephony;->endCall()Z
-Lcom/android/internal/telephony/ITelephony;->endCallForSubscriber(I)Z
 Lcom/android/internal/telephony/ITelephony;->getActivePhoneType()I
 Lcom/android/internal/telephony/ITelephony;->getCallState()I
 Lcom/android/internal/telephony/ITelephony;->getDataActivity()I
@@ -2108,12 +2100,8 @@
 Lcom/android/internal/telephony/ITelephony;->hasIccCard()Z
 Lcom/android/internal/telephony/ITelephony;->iccCloseLogicalChannel(II)Z
 Lcom/android/internal/telephony/ITelephony;->iccTransmitApduLogicalChannel(IIIIIIILjava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/ITelephony;->isIdleForSubscriber(ILjava/lang/String;)Z
 Lcom/android/internal/telephony/ITelephony;->isRadioOnForSubscriber(ILjava/lang/String;)Z
-Lcom/android/internal/telephony/ITelephony;->isRinging(Ljava/lang/String;)Z
 Lcom/android/internal/telephony/ITelephony;->setRadio(Z)Z
-Lcom/android/internal/telephony/ITelephony;->silenceRinger()V
 Lcom/android/internal/telephony/ITelephony;->supplyPin(Ljava/lang/String;)Z
 Lcom/android/internal/telephony/ITelephony;->toggleRadioOnOff()V
 Lcom/android/internal/telephony/ITelephony;->updateServiceLocation()V
@@ -2227,6 +2215,7 @@
 Lcom/android/org/conscrypt/OpenSSLKey;->fromPrivateKey(Ljava/security/PrivateKey;)Lcom/android/org/conscrypt/OpenSSLKey;
 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/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String;
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 63c583f..56ca98f 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -1022,6 +1022,7 @@
 android.graphics.-$$Lambda$ColorSpace$Rgb$bWzafC8vMHNuVmRuTUPEFUMlfuY
 android.graphics.-$$Lambda$ColorSpace$S2rlqJvkXGTpUF6mZhvkElds8JE
 android.graphics.BaseCanvas
+android.graphics.BaseRecordingCanvas
 android.graphics.Bitmap
 android.graphics.Bitmap$1
 android.graphics.Bitmap$2
@@ -2381,7 +2382,6 @@
 android.os.-$$Lambda$StrictMode$yZJXPvy2veRNA-xL_SWdXzX_OLg
 android.os.-$$Lambda$Trace$2zLZ-Lc2kAXsVjw_nLYeNhqmGq0
 android.os.AsyncResult
-android.os.AsyncTask
 android.os.AsyncTask$1
 android.os.AsyncTask$2
 android.os.AsyncTask$3
@@ -3304,7 +3304,6 @@
 android.view.OrientationEventListener$SensorEventListenerImpl
 android.view.PointerIcon
 android.view.PointerIcon$1
-android.view.RecordingCanvas
 android.view.RenderNode
 android.view.RenderNode$NoImagePreloadHolder
 android.view.RenderNodeAnimator
diff --git a/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist
index 8b8d640..eca3bf3 100644
--- a/config/preloaded-classes-blacklist
+++ b/config/preloaded-classes-blacklist
@@ -1,4 +1,5 @@
 android.net.ConnectivityThread$Singleton
+android.os.AsyncTask
 android.os.FileObserver
 android.widget.Magnifier
 sun.nio.fs.UnixChannelFactory
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 2ee266d..aca80b4 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -394,7 +394,7 @@
  *         <td>The final call you receive before your
  *             activity is destroyed.  This can happen either because the
  *             activity is finishing (someone called {@link Activity#finish} on
- *             it, or because the system is temporarily destroying this
+ *             it), or because the system is temporarily destroying this
  *             instance of the activity to save space.  You can distinguish
  *             between these two scenarios with the {@link
  *             Activity#isFinishing} method.</td>
@@ -1588,11 +1588,13 @@
      * @param outState The bundle to save the state to.
      */
     final void performSaveInstanceState(@NonNull Bundle outState) {
+        getApplication().dispatchActivityPreSaveInstanceState(this, outState);
         onSaveInstanceState(outState);
         saveManagedDialogs(outState);
         mActivityTransitionState.saveState(outState);
         storeHasCurrentPermissionRequest(outState);
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
+        getApplication().dispatchActivityPostSaveInstanceState(this, outState);
     }
 
     /**
@@ -1606,11 +1608,13 @@
      */
     final void performSaveInstanceState(@NonNull Bundle outState,
             @NonNull PersistableBundle outPersistentState) {
+        getApplication().dispatchActivityPreSaveInstanceState(this, outState);
         onSaveInstanceState(outState, outPersistentState);
         saveManagedDialogs(outState);
         storeHasCurrentPermissionRequest(outState);
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState +
                 ", " + outPersistentState);
+        getApplication().dispatchActivityPostSaveInstanceState(this, outState);
     }
 
     /**
@@ -1981,7 +1985,7 @@
     /**
      * Perform any final cleanup before an activity is destroyed.  This can
      * happen either because the activity is finishing (someone called
-     * {@link #finish} on it, or because the system is temporarily destroying
+     * {@link #finish} on it), or because the system is temporarily destroying
      * this instance of the activity to save space.  You can distinguish
      * between these two scenarios with the {@link #isFinishing} method.
      *
@@ -2948,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.
      *
@@ -3248,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
@@ -7195,6 +7199,7 @@
 
     @UnsupportedAppUsage
     final void performCreate(Bundle icicle, PersistableBundle persistentState) {
+        getApplication().dispatchActivityPreCreated(this, icicle);
         mCanEnterPictureInPicture = true;
         restoreHasCurrentPermissionRequest(icicle);
         if (persistentState != null) {
@@ -7209,6 +7214,7 @@
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
         mFragments.dispatchActivityCreated();
         mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
+        getApplication().dispatchActivityPostCreated(this, icicle);
     }
 
     final void performNewIntent(@NonNull Intent intent) {
@@ -7217,6 +7223,7 @@
     }
 
     final void performStart(String reason) {
+        getApplication().dispatchActivityPreStarted(this);
         mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
         mFragments.noteStateNotSaved();
         mCalled = false;
@@ -7284,6 +7291,7 @@
         }
 
         mActivityTransitionState.enterReady(this);
+        getApplication().dispatchActivityPostStarted(this);
     }
 
     /**
@@ -7338,6 +7346,7 @@
     }
 
     final void performResume(boolean followedByPause, String reason) {
+        getApplication().dispatchActivityPreResumed(this);
         performRestart(true /* start */, reason);
 
         mFragments.execPendingActions();
@@ -7387,9 +7396,11 @@
                 "Activity " + mComponent.toShortString() +
                 " did not call through to super.onPostResume()");
         }
+        getApplication().dispatchActivityPostResumed(this);
     }
 
     final void performPause() {
+        getApplication().dispatchActivityPrePaused(this);
         mDoReportFullyDrawn = false;
         mFragments.dispatchPause();
         mCalled = false;
@@ -7402,6 +7413,7 @@
                     "Activity " + mComponent.toShortString() +
                     " did not call through to super.onPause()");
         }
+        getApplication().dispatchActivityPostPaused(this);
     }
 
     final void performUserLeaving() {
@@ -7417,6 +7429,7 @@
         mCanEnterPictureInPicture = false;
 
         if (!mStopped) {
+            getApplication().dispatchActivityPreStopped(this);
             if (mWindow != null) {
                 mWindow.closeAllPanels();
             }
@@ -7451,11 +7464,13 @@
             }
 
             mStopped = true;
+            getApplication().dispatchActivityPostStopped(this);
         }
         mResumed = false;
     }
 
     final void performDestroy() {
+        getApplication().dispatchActivityPreDestroyed(this);
         mDestroyed = true;
         mWindow.destroy();
         mFragments.dispatchDestroy();
@@ -7465,6 +7480,7 @@
         if (mVoiceInteractor != null) {
             mVoiceInteractor.detachActivity();
         }
+        getApplication().dispatchActivityPostDestroyed(this);
     }
 
     final void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
@@ -7890,7 +7906,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 e86a49d..14b8ae4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -776,7 +776,7 @@
     /** @hide */
     public int getPackageScreenCompatMode(String packageName) {
         try {
-            return getService().getPackageScreenCompatMode(packageName);
+            return getTaskService().getPackageScreenCompatMode(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -785,7 +785,7 @@
     /** @hide */
     public void setPackageScreenCompatMode(String packageName, int mode) {
         try {
-            getService().setPackageScreenCompatMode(packageName, mode);
+            getTaskService().setPackageScreenCompatMode(packageName, mode);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -794,7 +794,7 @@
     /** @hide */
     public boolean getPackageAskScreenCompat(String packageName) {
         try {
-            return getService().getPackageAskScreenCompat(packageName);
+            return getTaskService().getPackageAskScreenCompat(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -803,7 +803,7 @@
     /** @hide */
     public void setPackageAskScreenCompat(String packageName, boolean ask) {
         try {
-            getService().setPackageAskScreenCompat(packageName, ask);
+            getTaskService().setPackageAskScreenCompat(packageName, ask);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3379,7 +3379,7 @@
      */
     public ConfigurationInfo getDeviceConfigurationInfo() {
         try {
-            return getService().getDeviceConfigurationInfo();
+            return getTaskService().getDeviceConfigurationInfo();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 87366db..784ce04 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -18,11 +18,15 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.IIntentReceiver;
 import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
+import android.os.Bundle;
 import android.os.IBinder;
+import android.os.TransactionTooLargeException;
 import android.view.RemoteAnimationAdapter;
 
 import java.util.ArrayList;
@@ -183,12 +187,6 @@
     /** Trims memory usage in the system by removing/stopping unused application processes. */
     public abstract void trimApplications();
 
-    /** Returns the screen compatibility mode for the given application. */
-    public abstract int getPackageScreenCompatMode(ApplicationInfo ai);
-
-    /** Sets the screen compatibility mode for the given application. */
-    public abstract void setPackageScreenCompatMode(ApplicationInfo ai, int mode);
-
     /** Closes all system dialogs. */
     public abstract void closeSystemDialogs(String reason);
 
@@ -201,6 +199,11 @@
     public abstract boolean hasRunningActivity(int uid, @Nullable String packageName);
 
     public abstract void updateOomAdj();
+    public abstract void updateCpuStats();
+    public abstract void updateUsageStats(
+            ComponentName activity, int uid, int userId, boolean resumed);
+    public abstract void updateForegroundTimeIfOnBattery(
+            String packageName, int uid, long cpuTimeDiff);
     public abstract void sendForegroundProfileChanged(int userId);
 
     /**
@@ -209,11 +212,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);
@@ -226,4 +224,22 @@
 
     /** Gets the task id for a given activity. */
     public abstract int getTaskIdForActivity(@NonNull IBinder token, boolean onlyRoot);
+
+    public abstract void setBooting(boolean booting);
+    public abstract boolean isBooting();
+    public abstract void setBooted(boolean booted);
+    public abstract boolean isBooted();
+    public abstract void finishBooting();
+
+    public abstract void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid,
+            long duration, String tag);
+    public abstract int broadcastIntentInPackage(String packageName, int uid, Intent intent,
+            String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData,
+            Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized,
+            boolean sticky, int userId);
+    public abstract ComponentName startServiceInPackage(int uid, Intent service,
+            String resolvedType, boolean fgRequired, String callingPackage, int userId)
+            throws TransactionTooLargeException;
+
+    public abstract void disconnectActivityFromServices(Object connectionHolder);
 }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 63c61d3..3c9a2d4 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1501,7 +1501,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/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 31e9a2d..ff6aca6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1541,7 +1541,7 @@
 
         public void scheduleTrimMemory(int level) {
             final Runnable r = PooledLambda.obtainRunnable(ActivityThread::handleTrimMemory,
-                    ActivityThread.this, level);
+                    ActivityThread.this, level).recycleOnUse();
             // Schedule trimming memory after drawing the frame to minimize jank-risk.
             Choreographer choreographer = Choreographer.getMainThreadInstance();
             if (choreographer != null) {
@@ -5666,7 +5666,7 @@
             }
         }
 
-        GraphicsEnvironment.getInstance().setup(context);
+        GraphicsEnvironment.getInstance().setup(context, mCoreSettings);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fd92174..a05d01b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -429,8 +429,8 @@
     /** @hide */
     @UnsupportedAppUsage
     public static final int OP_BLUETOOTH_SCAN = 77;
-    /** @hide Use the face authentication API. */
-    public static final int OP_USE_FACE = 78;
+    /** @hide Use the BiometricPrompt/BiometricManager APIs. */
+    public static final int OP_USE_BIOMETRIC = 78;
     /** @hide */
     @UnsupportedAppUsage
     public static final int _NUM_OP = 79;
@@ -678,8 +678,8 @@
     /** @hide */
     public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
 
-    /** @hide Use the face authentication API. */
-    public static final String OPSTR_USE_FACE = "android:use_face";
+    /** @hide Use the BiometricPrompt/BiometricManager APIs. */
+    public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
 
     // Warning: If an permission is added here it also has to be added to
     // com.android.packageinstaller.permission.utils.EventLogger
@@ -818,7 +818,7 @@
             OP_MANAGE_IPSEC_TUNNELS,            // MANAGE_IPSEC_HANDOVERS
             OP_START_FOREGROUND,                // START_FOREGROUND
             OP_COARSE_LOCATION,                 // BLUETOOTH_SCAN
-            OP_USE_FACE,                        // FACE
+            OP_USE_BIOMETRIC,                   // BIOMETRIC
     };
 
     /**
@@ -903,7 +903,7 @@
             OPSTR_MANAGE_IPSEC_TUNNELS,
             OPSTR_START_FOREGROUND,
             OPSTR_BLUETOOTH_SCAN,
-            OPSTR_USE_FACE,
+            OPSTR_USE_BIOMETRIC,
     };
 
     /**
@@ -989,7 +989,7 @@
             "MANAGE_IPSEC_TUNNELS",
             "START_FOREGROUND",
             "BLUETOOTH_SCAN",
-            "USE_FACE",
+            "USE_BIOMETRIC",
     };
 
     /**
@@ -1163,7 +1163,7 @@
             null, // MANAGE_IPSEC_TUNNELS
             null, // START_FOREGROUND
             null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
-            null, // USE_FACE
+            null, // USE_BIOMETRIC
     };
 
     /**
@@ -1249,92 +1249,92 @@
             false, // MANAGE_IPSEC_HANDOVERS
             false, // START_FOREGROUND
             true, // BLUETOOTH_SCAN
-            false, // USE_FACE
+            false, // USE_BIOMETRIC
     };
 
     /**
      * 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_FACE
+            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_DEFAULT, // READ_SMS
+            AppOpsManager.MODE_DEFAULT, // 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
     };
 
     /**
@@ -1345,85 +1345,85 @@
      * 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_FACE
+            false, // USE_BIOMETRIC
     };
 
     /**
@@ -1957,6 +1957,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/Application.java b/core/java/android/app/Application.java
index 68b745d..e12942f 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -65,13 +65,144 @@
     public LoadedApk mLoadedApk;
 
     public interface ActivityLifecycleCallbacks {
+
+        /**
+         * Called as the first step of the Activity being created. This is always called before
+         * {@link Activity#onCreate}.
+         */
+        default void onActivityPreCreated(@NonNull Activity activity,
+                @Nullable Bundle savedInstanceState) {
+        }
+
+        /**
+         * Called when the Activity calls {@link Activity#onCreate super.onCreate()}.
+         */
         void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState);
+
+        /**
+         * Called as the last step of the Activity being created. This is always called after
+         * {@link Activity#onCreate}.
+         */
+        default void onActivityPostCreated(@NonNull Activity activity,
+                @Nullable Bundle savedInstanceState) {
+        }
+
+        /**
+         * Called as the first step of the Activity being started. This is always called before
+         * {@link Activity#onStart}.
+         */
+        default void onActivityPreStarted(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called when the Activity calls {@link Activity#onStart super.onStart()}.
+         */
         void onActivityStarted(@NonNull Activity activity);
+
+        /**
+         * Called as the last step of the Activity being started. This is always called after
+         * {@link Activity#onStart}.
+         */
+        default void onActivityPostStarted(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called as the first step of the Activity being resumed. This is always called before
+         * {@link Activity#onResume}.
+         */
+        default void onActivityPreResumed(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called when the Activity calls {@link Activity#onResume super.onResume()}.
+         */
         void onActivityResumed(@NonNull Activity activity);
+
+        /**
+         * Called as the last step of the Activity being resumed. This is always called after
+         * {@link Activity#onResume} and {@link Activity#onPostResume}.
+         */
+        default void onActivityPostResumed(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called as the first step of the Activity being paused. This is always called before
+         * {@link Activity#onPause}.
+         */
+        default void onActivityPrePaused(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called when the Activity calls {@link Activity#onPause super.onPause()}.
+         */
         void onActivityPaused(@NonNull Activity activity);
+
+        /**
+         * Called as the last step of the Activity being paused. This is always called after
+         * {@link Activity#onPause}.
+         */
+        default void onActivityPostPaused(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called as the first step of the Activity being stopped. This is always called before
+         * {@link Activity#onStop}.
+         */
+        default void onActivityPreStopped(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called when the Activity calls {@link Activity#onStop super.onStop()}.
+         */
         void onActivityStopped(@NonNull Activity activity);
+
+        /**
+         * Called as the last step of the Activity being stopped. This is always called after
+         * {@link Activity#onStop}.
+         */
+        default void onActivityPostStopped(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called as the first step of the Activity saving its instance state. This is always
+         * called before {@link Activity#onSaveInstanceState}.
+         */
+        default void onActivityPreSaveInstanceState(@NonNull Activity activity,
+                @NonNull Bundle outState) {
+        }
+
+        /**
+         * Called when the Activity calls
+         * {@link Activity#onSaveInstanceState super.onSaveInstanceState()}.
+         */
         void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState);
+
+        /**
+         * Called as the last step of the Activity saving its instance state. This is always
+         * called after{@link Activity#onSaveInstanceState}.
+         */
+        default void onActivityPostSaveInstanceState(@NonNull Activity activity,
+                @NonNull Bundle outState) {
+        }
+
+        /**
+         * Called as the first step of the Activity being destroyed. This is always called before
+         * {@link Activity#onDestroy}.
+         */
+        default void onActivityPreDestroyed(@NonNull Activity activity) {
+        }
+
+        /**
+         * Called when the Activity calls {@link Activity#onDestroy super.onDestroy()}.
+         */
         void onActivityDestroyed(@NonNull Activity activity);
+
+        /**
+         * Called as the last step of the Activity being destroyed. This is always called after
+         * {@link Activity#onDestroy}.
+         */
+        default void onActivityPostDestroyed(@NonNull Activity activity) {
+        }
     }
 
     /**
@@ -222,6 +353,18 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPreCreated(@NonNull Activity activity,
+            @Nullable Bundle savedInstanceState) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreCreated(activity,
+                        savedInstanceState);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivityCreated(@NonNull Activity activity,
             @Nullable Bundle savedInstanceState) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
@@ -234,6 +377,28 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostCreated(@NonNull Activity activity,
+            @Nullable Bundle savedInstanceState) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostCreated(activity,
+                        savedInstanceState);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPreStarted(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreStarted(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivityStarted(@NonNull Activity activity) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
         if (callbacks != null) {
@@ -244,6 +409,26 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostStarted(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStarted(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPreResumed(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreResumed(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivityResumed(@NonNull Activity activity) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
         if (callbacks != null) {
@@ -254,6 +439,26 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostResumed(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostResumed(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPrePaused(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPrePaused(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivityPaused(@NonNull Activity activity) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
         if (callbacks != null) {
@@ -264,6 +469,26 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostPaused(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostPaused(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPreStopped(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreStopped(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivityStopped(@NonNull Activity activity) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
         if (callbacks != null) {
@@ -274,6 +499,28 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostStopped(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStopped(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPreSaveInstanceState(@NonNull Activity activity,
+            @NonNull Bundle outState) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreSaveInstanceState(
+                        activity, outState);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivitySaveInstanceState(@NonNull Activity activity,
             @NonNull Bundle outState) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
@@ -286,6 +533,28 @@
     }
 
     @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostSaveInstanceState(@NonNull Activity activity,
+            @NonNull Bundle outState) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostSaveInstanceState(
+                        activity, outState);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPreDestroyed(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreDestroyed(activity);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
     /* package */ void dispatchActivityDestroyed(@NonNull Activity activity) {
         Object[] callbacks = collectActivityLifecycleCallbacks();
         if (callbacks != null) {
@@ -295,6 +564,16 @@
         }
     }
 
+    @UnsupportedAppUsage
+        /* package */ void dispatchActivityPostDestroyed(@NonNull Activity activity) {
+        Object[] callbacks = collectActivityLifecycleCallbacks();
+        if (callbacks != null) {
+            for (int i = 0; i < callbacks.length; i++) {
+                ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostDestroyed(activity);
+            }
+        }
+    }
+
     private Object[] collectComponentCallbacks() {
         Object[] callbacks = null;
         synchronized (mComponentCallbacks) {
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 37a05f0..9d82ffa 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -239,7 +239,7 @@
          * @param year the selected year
          * @param month the selected month (0-11 for compatibility with
          *              {@link Calendar#MONTH})
-         * @param dayOfMonth th selected day of the month (1-31, depending on
+         * @param dayOfMonth the selected day of the month (1-31, depending on
          *                   month)
          */
         void onDateSet(DatePicker view, int year, int month, int dayOfMonth);
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/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 16360b3..519a274 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -208,8 +208,6 @@
     List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags);
     // Retrieve running application processes in the system
     List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses();
-    // Get device configuration
-    ConfigurationInfo getDeviceConfigurationInfo();
     IBinder peekService(in Intent service, in String resolvedType, in String callingPackage);
     // Turn on/off profiling in a particular process.
     boolean profileControl(in String process, int userId, boolean start,
@@ -248,10 +246,7 @@
             boolean runGc, in String path, in ParcelFileDescriptor fd,
             in RemoteCallback finishCallback);
     boolean isUserRunning(int userid, int flags);
-    int getPackageScreenCompatMode(in String packageName);
     void setPackageScreenCompatMode(in String packageName, int mode);
-    boolean getPackageAskScreenCompat(in String packageName);
-    void setPackageAskScreenCompat(in String packageName, boolean ask);
     boolean switchUser(int userid);
     boolean removeTask(int taskId);
     void registerProcessObserver(in IProcessObserver observer);
@@ -263,7 +258,9 @@
     void killAllBackgroundProcesses();
     ContentProviderHolder getContentProviderExternal(in String name, int userId,
             in IBinder token, String tag);
+    /** @deprecated - Use {@link #removeContentProviderExternalAsUser} which takes a user ID. */
     void removeContentProviderExternal(in String name, in IBinder token);
+    void removeContentProviderExternalAsUser(in String name, in IBinder token, int userId);
     // Get memory information about the calling process.
     void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo);
     boolean killProcessesBelowForeground(in String reason);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 46664c6..b7b6352 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -344,6 +344,9 @@
     void notifyPinnedStackAnimationStarted();
     void notifyPinnedStackAnimationEnded();
 
+    // Get device configuration
+    ConfigurationInfo getDeviceConfigurationInfo();
+
     /**
      * Resizes the pinned stack.
      *
@@ -422,4 +425,9 @@
     void resumeAppSwitches();
     void setActivityController(in IActivityController watcher, boolean imAMonkey);
     void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake);
+
+    int getPackageScreenCompatMode(in String packageName);
+    void setPackageScreenCompatMode(in String packageName, int mode);
+    boolean getPackageAskScreenCompat(in String packageName);
+    void setPackageAskScreenCompat(in String packageName, boolean ask);
 }
diff --git a/core/java/android/app/ISmsAppService.aidl b/core/java/android/app/ISmsAppService.aidl
new file mode 100644
index 0000000..1ac2ec6
--- /dev/null
+++ b/core/java/android/app/ISmsAppService.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+/**
+ * @hide
+ */
+interface ISmsAppService {
+}
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 3638bc4..1589306 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4440,7 +4440,7 @@
         }
 
         private CharSequence processTextSpans(CharSequence text) {
-            if (hasForegroundColor()) {
+            if (hasForegroundColor() || mInNightMode) {
                 return ContrastColorUtil.clearColorSpans(text);
             }
             return text;
@@ -6203,7 +6203,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 +6690,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 +7346,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() {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 9f819b9..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<>();
     }
 
     /**
@@ -1636,11 +1642,14 @@
         try {
             final ParceledListSlice<StatusBarNotification> parceledList
                     = service.getAppActiveNotifications(pkg, mContext.getUserId());
-            final List<StatusBarNotification> list = parceledList.getList();
-            return list.toArray(new StatusBarNotification[list.size()]);
+            if (parceledList != null) {
+                final List<StatusBarNotification> list = parceledList.getList();
+                return list.toArray(new StatusBarNotification[list.size()]);
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
+        return new StatusBarNotification[0];
     }
 
     /**
diff --git a/core/java/android/app/ProcessMemoryState.java b/core/java/android/app/ProcessMemoryState.java
index 39db16d..9bfdae0 100644
--- a/core/java/android/app/ProcessMemoryState.java
+++ b/core/java/android/app/ProcessMemoryState.java
@@ -23,19 +23,20 @@
  * The memory stats for a process.
  * {@hide}
  */
-public class ProcessMemoryState implements Parcelable {
-    public int uid;
-    public String processName;
-    public int oomScore;
-    public long pgfault;
-    public long pgmajfault;
-    public long rssInBytes;
-    public long cacheInBytes;
-    public long swapInBytes;
+public final class ProcessMemoryState implements Parcelable {
+    public final int uid;
+    public final String processName;
+    public final int oomScore;
+    public final long pgfault;
+    public final long pgmajfault;
+    public final long rssInBytes;
+    public final long cacheInBytes;
+    public final long swapInBytes;
+    public final long rssHighWatermarkInBytes;
 
     public ProcessMemoryState(int uid, String processName, int oomScore, long pgfault,
                               long pgmajfault, long rssInBytes, long cacheInBytes,
-                              long swapInBytes) {
+                              long swapInBytes, long rssHighWatermarkInBytes) {
         this.uid = uid;
         this.processName = processName;
         this.oomScore = oomScore;
@@ -44,6 +45,7 @@
         this.rssInBytes = rssInBytes;
         this.cacheInBytes = cacheInBytes;
         this.swapInBytes = swapInBytes;
+        this.rssHighWatermarkInBytes = rssHighWatermarkInBytes;
     }
 
     private ProcessMemoryState(Parcel in) {
@@ -55,6 +57,7 @@
         rssInBytes = in.readLong();
         cacheInBytes = in.readLong();
         swapInBytes = in.readLong();
+        rssHighWatermarkInBytes = in.readLong();
     }
 
     public static final Creator<ProcessMemoryState> CREATOR = new Creator<ProcessMemoryState>() {
@@ -84,5 +87,6 @@
         parcel.writeLong(rssInBytes);
         parcel.writeLong(cacheInBytes);
         parcel.writeLong(swapInBytes);
+        parcel.writeLong(rssHighWatermarkInBytes);
     }
 }
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
new file mode 100644
index 0000000..3829d71
--- /dev/null
+++ b/core/java/android/app/SmsAppService.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ComponentName;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * If the default SMS app has a service that extends this class, the system always tries to bind
+ * 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 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>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 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;
+
+    public SmsAppService() {
+        mImpl = new ISmsAppServiceImpl();
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return mImpl.asBinder();
+    }
+
+    private class ISmsAppServiceImpl extends ISmsAppService.Stub {
+    }
+}
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 2718bfa..bf3d885 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.annotation.SystemService;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -208,10 +209,11 @@
     }
 
     /**
-     * Expand the settings panel and open a subPanel, pass null to just open the settings panel.
+     * Expand the settings panel and open a subPanel. If the subpanel is null or does not have a
+     * corresponding tile, the QS panel is simply expanded
      */
     @UnsupportedAppUsage
-    public void expandSettingsPanel(String subPanel) {
+    public void expandSettingsPanel(@Nullable String subPanel) {
         try {
             final IStatusBarService svc = getService();
             if (svc != null) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 003f364..6c87fe7 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -53,6 +53,8 @@
 import android.hardware.SensorManager;
 import android.hardware.SerialManager;
 import android.hardware.SystemSensorManager;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.IBiometricService;
 import android.hardware.camera2.CameraManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.face.FaceManager;
@@ -132,6 +134,7 @@
 import android.os.Vibrator;
 import android.os.health.SystemHealthManager;
 import android.os.storage.StorageManager;
+import android.permission.PermissionManager;
 import android.print.IPrintManager;
 import android.print.PrintManager;
 import android.service.oemlock.IOemLockService;
@@ -374,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.getInstance();
+            public InputMethodManager getService(ContextImpl ctx) {
+                return InputMethodManager.forContext(ctx);
             }});
 
         registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class,
@@ -818,6 +825,19 @@
                     }
                 });
 
+        registerService(Context.BIOMETRIC_SERVICE, BiometricManager.class,
+                new CachedServiceFetcher<BiometricManager>() {
+                    @Override
+                    public BiometricManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        final IBinder binder =
+                                ServiceManager.getServiceOrThrow(Context.BIOMETRIC_SERVICE);
+                        final IBiometricService service =
+                                IBiometricService.Stub.asInterface(binder);
+                        return new BiometricManager(ctx.getOuterContext(), service);
+                    }
+                });
+
         registerService(Context.TV_INPUT_SERVICE, TvInputManager.class,
                 new CachedServiceFetcher<TvInputManager>() {
             @Override
@@ -1049,6 +1069,13 @@
                             throws ServiceNotFoundException {
                         return new TimeZoneDetector();
                     }});
+
+        registerService(Context.PERMISSION_SERVICE, PermissionManager.class,
+                new CachedServiceFetcher<PermissionManager>() {
+                    @Override
+                    public PermissionManager createService(ContextImpl ctx) {
+                        return new PermissionManager(ctx.getOuterContext());
+                    }});
     }
 
     /**
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index c0903b6..5a25f5a 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1197,10 +1197,9 @@
                     }
                     if (listener != null) {
                         // Calling out only without a lock held.
-                        mLocalCallbackHandler.post(PooledLambda.obtainRunnable(
+                        mLocalCallbackHandler.sendMessage(PooledLambda.obtainMessage(
                                 OnAccessibilityEventListener::onAccessibilityEvent,
-                                listener, AccessibilityEvent.obtain(event))
-                                .recycleOnUse());
+                                listener, AccessibilityEvent.obtain(event)));
                     }
                 }
 
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 4f172a4..a554882 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -25,7 +25,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
-import android.util.Log;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -214,7 +213,7 @@
     }
 
     /**
-     * Sets the night mode.
+     * Sets the system-wide night mode.
      * <p>
      * The mode can be one of:
      * <ul>
@@ -231,6 +230,12 @@
      * are only effective when the {@link Configuration#UI_MODE_TYPE_CAR car}
      * or {@link Configuration#UI_MODE_TYPE_DESK desk} mode is enabled on a
      * device. Starting in API 23, changes to night mode are always effective.
+     * <p>
+     * Changes to night mode take effect globally and will result in a configuration change
+     * (and potentially an Activity lifecycle event) being applied to all running apps.
+     * Developers interested in an app-local implementation of night mode should consider using
+     * {@link android.support.v7.app.AppCompatDelegate#setDefaultNightMode(int)} to manage the
+     * -night qualifier locally.
      *
      * @param mode the night mode to set
      * @see #getNightMode()
diff --git a/core/java/android/app/WaitResult.java b/core/java/android/app/WaitResult.java
index 898d0ca..5baf2e2 100644
--- a/core/java/android/app/WaitResult.java
+++ b/core/java/android/app/WaitResult.java
@@ -28,10 +28,10 @@
  * @hide
  */
 public class WaitResult implements Parcelable {
+    public static final int INVALID_DELAY = -1;
     public int result;
     public boolean timeout;
     public ComponentName who;
-    public long thisTime;
     public long totalTime;
 
     public WaitResult() {
@@ -47,7 +47,6 @@
         dest.writeInt(result);
         dest.writeInt(timeout ? 1 : 0);
         ComponentName.writeToParcel(who, dest);
-        dest.writeLong(thisTime);
         dest.writeLong(totalTime);
     }
 
@@ -68,7 +67,6 @@
         result = source.readInt();
         timeout = source.readInt() != 0;
         who = ComponentName.readFromParcel(source);
-        thisTime = source.readLong();
         totalTime = source.readLong();
     }
 
@@ -77,7 +75,6 @@
         pw.println(prefix + "  result=" + result);
         pw.println(prefix + "  timeout=" + timeout);
         pw.println(prefix + "  who=" + who);
-        pw.println(prefix + "  thisTime=" + thisTime);
         pw.println(prefix + "  totalTime=" + totalTime);
     }
 }
\ No newline at end of file
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index e6fb5dc..096c7aa 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -28,9 +28,13 @@
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
+import android.util.proto.WireTypeMismatchException;
 import android.view.DisplayInfo;
 
+import java.io.IOException;
+
 /**
  * Class that contains windowing configuration/state for other objects that contain windows directly
  * or indirectly. E.g. Activities, Task, Displays, ...
@@ -511,6 +515,38 @@
     }
 
     /**
+     * Read from a protocol buffer input stream.
+     * Protocol buffer message definition at {@link android.app.WindowConfigurationProto}
+     *
+     * @param proto   Stream to read the WindowConfiguration object from.
+     * @param fieldId Field Id of the WindowConfiguration as defined in the parent message
+     * @hide
+     */
+    public void readFromProto(ProtoInputStream proto, long fieldId)
+            throws IOException, WireTypeMismatchException {
+        final long token = proto.start(fieldId);
+        try {
+            while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                switch (proto.getFieldNumber()) {
+                    case (int) APP_BOUNDS:
+                        mAppBounds = new Rect();
+                        mAppBounds.readFromProto(proto, APP_BOUNDS);
+                        break;
+                    case (int) WINDOWING_MODE:
+                        mWindowingMode = proto.readInt(WINDOWING_MODE);
+                        break;
+                    case (int) ACTIVITY_TYPE:
+                        mActivityType = proto.readInt(ACTIVITY_TYPE);
+                        break;
+                }
+            }
+        } finally {
+            // Let caller handle any exceptions
+            proto.end(token);
+        }
+    }
+
+    /**
      * Returns true if the activities associated with this window configuration display a shadow
      * around their border.
      * @hide
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index bd7a2dd..a1b8d86 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -664,8 +664,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 +680,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 +1148,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
@@ -3304,7 +3399,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) {
@@ -3450,15 +3545,14 @@
      * @param flags Bit mask of additional options: currently supported flags are
      *            {@link #WIPE_EXTERNAL_STORAGE} and {@link #WIPE_RESET_PROTECTION_DATA}.
      * @param reason a string that contains the reason for wiping data, which can be
-     *                          presented to the user.
+     *            presented to the user. If the string is null or empty, user won't be notified.
      * @throws SecurityException if the calling application does not own an active administrator
      *             that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}
      * @throws IllegalArgumentException if the input reason string is null or empty.
      */
-    public void wipeData(int flags, @NonNull CharSequence reason) {
+    public void wipeData(int flags, CharSequence reason) {
         throwIfParentInstance("wipeData");
-        Preconditions.checkNotNull(reason, "CharSequence is null");
-        wipeDataInternal(flags, reason.toString());
+        wipeDataInternal(flags, reason != null ? reason.toString() : null);
     }
 
     /**
@@ -3469,7 +3563,7 @@
      * @see #wipeData(int, CharSequence)
      * @hide
      */
-    private void wipeDataInternal(int flags, @NonNull String wipeReasonForUser) {
+    private void wipeDataInternal(int flags, String wipeReasonForUser) {
         if (mService != null) {
             try {
                 mService.wipeDataWithReason(flags, wipeReasonForUser);
@@ -7405,6 +7499,10 @@
      * If any app targeting {@link android.os.Build.VERSION_CODES#O} or higher calls this method
      * with {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS},
      * an {@link UnsupportedOperationException} is thrown.
+     *
+     * Starting from Android Q, the device and profile owner can also call
+     * {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY} to restrict unknown sources for
+     * all users.
      * </strong>
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 173b766..c1ca636 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1002,7 +1002,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 +1028,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 +1350,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/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 9f22ad1..308b39e 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -165,6 +165,12 @@
          */
         public static final int KEYGUARD_HIDDEN = 18;
 
+        /**
+         * Keep in sync with the greatest event type value.
+         * @hide
+         */
+        public static final int MAX_EVENT_TYPE = 18;
+
         /** @hide */
         public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;
 
@@ -176,6 +182,12 @@
         public @interface EventFlags {}
 
         /**
+         * Bitwise OR all valid flag constants to create this constant.
+         * @hide
+         */
+        public static final int VALID_FLAG_BITS = FLAG_IS_PACKAGE_INSTANT_APP;
+
+        /**
          * {@hide}
          */
         @UnsupportedAppUsage
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/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 73e98cd..30d5fbc 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1596,7 +1596,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 +1631,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 +1688,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
@@ -1972,7 +1972,7 @@
      * 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,
+     * secure socket connection is not possible, use {@link createInsecureLeL2capCocSocket(int,
      * int)}.
      *
      * @param psm dynamic PSM value from remote device
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 183be5f..559a59b 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -73,6 +73,8 @@
     /** Connection canceled before completion. */
     public static final int RESULT_CANCELED = 2;
 
+    private static final int UPLOADING_FEATURE_BITMASK = 0x08;
+
     private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
                 public void onBluetoothStateChange(boolean up) {
@@ -395,6 +397,23 @@
         return false;
     }
 
+    /**
+     * Returns the "Uploading" feature bit value from the SDP record's
+     * MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114).
+     * @param device The Bluetooth device to get this value for.
+     * @return Returns true if the Uploading bit value in SDP record's
+     *         MapSupportedFeatures field is set. False is returned otherwise.
+     */
+    public boolean isUploadingSupported(BluetoothDevice device) {
+        try {
+            return (mService != null && isEnabled() && isValidDevice(device))
+                && ((mService.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, e.getMessage());
+        }
+        return false;
+    }
+
     private final ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 5fc344a..758c68d 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -203,7 +203,7 @@
     /**
      * 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
+     * {@link BluetoothAdapter.listenUsingL2capChannel()} or {@link
      * BluetoothAdapter.listenUsingInsecureL2capChannel()}. The returned value is undefined if this
      * method is called on non-L2CAP server sockets.
      *
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 3fe17840..8760efe 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -95,9 +95,6 @@
      * Sets the current primary clip on the clipboard.  This is the clip that
      * is involved in normal cut and paste operations.
      *
-     * <em>If the application is not the default IME or does not have input focus this will have
-     * no effect.</em>
-     *
      * @param clip The clipped data item to set.
      * @see #getPrimaryClip()
      * @see #clearPrimaryClip()
@@ -115,9 +112,6 @@
     /**
      * Clears any current primary clip on the clipboard.
      *
-     * <em>If the application is not the default IME or does not have input focus this will have
-     * no effect.</em>
-     *
      * @see #setPrimaryClip(ClipData)
      */
     public void clearPrimaryClip() {
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index bd1e6a4..2a03787 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;
@@ -51,6 +52,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
@@ -58,6 +61,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Objects;
 
 /**
  * Content providers are one of the primary building blocks of Android applications, providing
@@ -99,6 +103,7 @@
  * <p>For more information about using content providers, read the
  * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
  * developer guide.</p>
+ * </div>
  */
 public abstract class ContentProvider implements ComponentCallbacks2 {
 
@@ -220,7 +225,7 @@
         @Override
         public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
                 @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 // The caller has no access to the data, so return an empty cursor with
@@ -268,7 +273,7 @@
         @Override
         public String getType(Uri uri) {
             // getCallingPackage() isn't available in getType(), as the javadoc states.
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             Trace.traceBegin(TRACE_TAG_DATABASE, "getType");
             try {
@@ -280,7 +285,7 @@
 
         @Override
         public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
@@ -303,7 +308,7 @@
 
         @Override
         public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
@@ -327,11 +332,12 @@
             for (int i = 0; i < numOperations; i++) {
                 ContentProviderOperation operation = operations.get(i);
                 Uri uri = operation.getUri();
-                validateIncomingUri(uri);
                 userIds[i] = getUserIdFromUri(uri);
-                if (userIds[i] != UserHandle.USER_CURRENT) {
-                    // Removing the user id from the uri.
-                    operation = new ContentProviderOperation(operation, true);
+                uri = validateIncomingUri(uri);
+                uri = maybeGetUriWithoutUserId(uri);
+                // Rebuild operation if we changed the Uri above
+                if (!Objects.equals(operation.getUri(), uri)) {
+                    operation = new ContentProviderOperation(operation, uri);
                     operations.set(i, operation);
                 }
                 if (operation.isReadOperation()) {
@@ -368,7 +374,7 @@
 
         @Override
         public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
@@ -386,7 +392,7 @@
         @Override
         public int update(String callingPkg, Uri uri, ContentValues values, String selection,
                 String[] selectionArgs) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
@@ -405,7 +411,7 @@
         public ParcelFileDescriptor openFile(
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal,
                 IBinder callerToken) throws FileNotFoundException {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             enforceFilePermission(callingPkg, uri, mode, callerToken);
             Trace.traceBegin(TRACE_TAG_DATABASE, "openFile");
@@ -423,7 +429,7 @@
         public AssetFileDescriptor openAssetFile(
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             enforceFilePermission(callingPkg, uri, mode, null);
             Trace.traceBegin(TRACE_TAG_DATABASE, "openAssetFile");
@@ -454,7 +460,7 @@
         @Override
         public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
             // getCallingPackage() isn't available in getType(), as the javadoc states.
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             Trace.traceBegin(TRACE_TAG_DATABASE, "getStreamTypes");
             try {
@@ -468,7 +474,7 @@
         public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
                 Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
             Bundle.setDefusable(opts, true);
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             enforceFilePermission(callingPkg, uri, "r", null);
             Trace.traceBegin(TRACE_TAG_DATABASE, "openTypedAssetFile");
@@ -489,7 +495,7 @@
 
         @Override
         public Uri canonicalize(String callingPkg, Uri uri) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
@@ -507,7 +513,7 @@
 
         @Override
         public Uri uncanonicalize(String callingPkg, Uri uri) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
@@ -526,7 +532,7 @@
         @Override
         public boolean refresh(String callingPkg, Uri uri, Bundle args,
                 ICancellationSignal cancellationSignal) throws RemoteException {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return false;
@@ -564,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)
@@ -578,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;
@@ -604,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} */
@@ -1965,7 +1977,7 @@
          */
         if (mContext == null) {
             mContext = context;
-            if (context != null) {
+            if (context != null && mTransport != null) {
                 mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(
                         Context.APP_OPS_SERVICE);
             }
@@ -2074,7 +2086,8 @@
     }
 
     /** @hide */
-    private void validateIncomingUri(Uri uri) throws SecurityException {
+    @VisibleForTesting
+    public Uri validateIncomingUri(Uri uri) throws SecurityException {
         String auth = uri.getAuthority();
         if (!mSingleUser) {
             int userId = getUserIdFromAuthority(auth, UserHandle.USER_CURRENT);
@@ -2093,6 +2106,19 @@
             }
             throw new SecurityException(message);
         }
+
+        // Normalize the path by removing any empty path segments, which can be
+        // a source of security issues.
+        final String encodedPath = uri.getEncodedPath();
+        if (encodedPath != null && encodedPath.indexOf("//") != -1) {
+            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;
+        }
     }
 
     /** @hide */
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index e3d9b19..7dc4577 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -101,13 +101,9 @@
     }
 
     /** @hide */
-    public ContentProviderOperation(ContentProviderOperation cpo, boolean removeUserIdFromUri) {
+    public ContentProviderOperation(ContentProviderOperation cpo, Uri withUri) {
         mType = cpo.mType;
-        if (removeUserIdFromUri) {
-            mUri = ContentProvider.getUriWithoutUserId(cpo.mUri);
-        } else {
-            mUri = cpo.mUri;
-        }
+        mUri = withUri;
         mValues = cpo.mValues;
         mSelection = cpo.mSelection;
         mSelectionArgs = cpo.mSelectionArgs;
@@ -117,14 +113,6 @@
         mYieldAllowed = cpo.mYieldAllowed;
     }
 
-    /** @hide */
-    public ContentProviderOperation getWithoutUserIdInUri() {
-        if (ContentProvider.uriHasUserId(mUri)) {
-            return new ContentProviderOperation(this, true);
-        }
-        return this;
-    }
-
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mType);
         Uri.writeToParcel(dest, mUri);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2ae3ae6..d711574 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3031,6 +3031,7 @@
             AUDIO_SERVICE,
             FINGERPRINT_SERVICE,
             //@hide: FACE_SERVICE,
+            BIOMETRIC_SERVICE,
             MEDIA_ROUTER_SERVICE,
             TELEPHONY_SERVICE,
             TELEPHONY_SUBSCRIPTION_SERVICE,
@@ -3087,6 +3088,7 @@
             //@hide: SYSTEM_UPDATE_SERVICE,
             //@hide: TIME_DETECTOR_SERVICE,
             //@hide: TIME_ZONE_DETECTOR_SERVICE,
+            PERMISSION_SERVICE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceName {}
@@ -3167,11 +3169,11 @@
      *
      * <p>Note: Instant apps, for which {@link PackageManager#isInstantApp()} returns true,
      * don't have access to the following system services: {@link #DEVICE_POLICY_SERVICE},
-     * {@link #FINGERPRINT_SERVICE}, {@link #SHORTCUT_SERVICE}, {@link #USB_SERVICE},
-     * {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE}, {@link #WIFI_SERVICE},
-     * {@link #WIFI_AWARE_SERVICE}. For these services this method will return <code>null</code>.
-     * Generally, if you are running as an instant app you should always check whether the result
-     * of this method is null.
+     * {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE},
+     * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
+     * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
+     * return <code>null</code>.  Generally, if you are running as an instant app you should always
+     * check whether the result of this method is null.
      *
      * @param name The name of the desired service.
      *
@@ -3258,11 +3260,11 @@
      *
      * <p>Note: Instant apps, for which {@link PackageManager#isInstantApp()} returns true,
      * don't have access to the following system services: {@link #DEVICE_POLICY_SERVICE},
-     * {@link #FINGERPRINT_SERVICE}, {@link #SHORTCUT_SERVICE}, {@link #USB_SERVICE},
-     * {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE}, {@link #WIFI_SERVICE},
-     * {@link #WIFI_AWARE_SERVICE}. For these services this method will return <code>null</code>.
-     * Generally, if you are running as an instant app you should always check whether the result
-     * of this method is null.
+     * {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE},
+     * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
+     * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
+     * return <code>null</code>.  Generally, if you are running as an instant app you should always
+     * check whether the result of this method is null.
      *
      * @param serviceClass The class of the desired service.
      * @return The service or null if the class is not a supported system service.
@@ -3681,15 +3683,6 @@
     public static final String AUDIO_SERVICE = "audio";
 
     /**
-     * Use with {@link #getSystemService(String)}
-     *
-     * @hide
-     * @see #getSystemService(String)
-     * @see com.android.server.biometrics.BiometricPromptService
-     */
-    public static final String BIOMETRIC_PROMPT_SERVICE = "biometric_prompt";
-
-    /**
      * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.hardware.fingerprint.FingerprintManager} for handling management
      * of fingerprints.
@@ -3701,7 +3694,6 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
-     * Use with {@link #getSystemService} to retrieve a
      * {@link android.hardware.face.FaceManager} for handling management
      * of face authentication.
      *
@@ -3712,6 +3704,16 @@
     public static final String FACE_SERVICE = "face";
 
     /**
+     * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.hardware.biometrics.BiometricManager} for handling management
+     * of face authentication.
+     *
+     * @see #getSystemService
+     * @see android.hardware.biometrics.BiometricManager
+     */
+    public static final String BIOMETRIC_SERVICE = "biometric";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.media.MediaRouter} for controlling and managing
      * routing of media.
@@ -3859,6 +3861,14 @@
      */
     public static final String SOUND_TRIGGER_SERVICE = "soundtrigger";
 
+    /**
+     * Official published name of the (internal) permission service.
+     *
+     * @see #getSystemService(String)
+     * @hide
+     */
+    @SystemApi
+    public static final String PERMISSION_SERVICE = "permission";
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
@@ -4301,6 +4311,12 @@
     public static final String TIME_ZONE_DETECTOR_SERVICE = "time_zone_detector";
 
     /**
+     * Binder service name for {@link AppBindingService}.
+     * @hide
+     */
+    public static final String APP_BINDING_SERVICE = "app_binding";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3c8d9d03..af910e0 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";
 
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 963f881..00aa5c2 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -102,10 +102,14 @@
 
     private static volatile boolean sForceSafeLabels = false;
 
-    /** {@hide} */
+    /**
+     * Always use {@link #loadSafeLabel safe labels} when calling {@link #loadLabel}.
+     *
+     * @hide
+     */
     @SystemApi
-    public static void setForceSafeLabels(boolean forceSafeLabels) {
-        sForceSafeLabels = forceSafeLabels;
+    public static void forceSafeLabels() {
+        sForceSafeLabels = true;
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a15711f5..3032d16 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1170,6 +1170,14 @@
     public static final int INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE = -27;
 
     /**
+     * Installation return code: this is passed in the {@link PackageInstaller#EXTRA_LEGACY_STATUS}
+     * if the new package requires at least one split and it was not provided.
+     *
+     * @hide
+     */
+    public static final int INSTALL_FAILED_MISSING_SPLIT = -28;
+
+    /**
      * Installation parse return code: this is passed in the
      * {@link PackageInstaller#EXTRA_LEGACY_STATUS} if the parser was given a path that is not a
      * file, or does not end with the expected '.apk' extension.
@@ -5927,8 +5935,8 @@
             case INSTALL_FAILED_DUPLICATE_PERMISSION: return "INSTALL_FAILED_DUPLICATE_PERMISSION";
             case INSTALL_FAILED_NO_MATCHING_ABIS: return "INSTALL_FAILED_NO_MATCHING_ABIS";
             case INSTALL_FAILED_ABORTED: return "INSTALL_FAILED_ABORTED";
-            case INSTALL_FAILED_BAD_DEX_METADATA:
-                return "INSTALL_FAILED_BAD_DEX_METADATA";
+            case INSTALL_FAILED_BAD_DEX_METADATA: return "INSTALL_FAILED_BAD_DEX_METADATA";
+            case INSTALL_FAILED_MISSING_SPLIT: return "INSTALL_FAILED_MISSING_SPLIT";
             default: return Integer.toString(status);
         }
     }
@@ -5979,6 +5987,7 @@
             case INSTALL_FAILED_DUPLICATE_PERMISSION: return PackageInstaller.STATUS_FAILURE_CONFLICT;
             case INSTALL_FAILED_NO_MATCHING_ABIS: return PackageInstaller.STATUS_FAILURE_INCOMPATIBLE;
             case INSTALL_FAILED_ABORTED: return PackageInstaller.STATUS_FAILURE_ABORTED;
+            case INSTALL_FAILED_MISSING_SPLIT: return PackageInstaller.STATUS_FAILURE_INCOMPATIBLE;
             default: return PackageInstaller.STATUS_FAILURE;
         }
     }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 03a3d1f..24675d3 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -40,7 +40,6 @@
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
 
-import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -73,6 +72,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
+import android.permission.PermissionManager;
 import android.system.ErrnoException;
 import android.system.OsConstants;
 import android.system.StructStat;
@@ -258,19 +258,6 @@
         }
     }
 
-    /** @hide */
-    public static class SplitPermissionInfo {
-        public final String rootPerm;
-        public final String[] newPerms;
-        public final int targetSdk;
-
-        public SplitPermissionInfo(String rootPerm, String[] newPerms, int targetSdk) {
-            this.rootPerm = rootPerm;
-            this.newPerms = newPerms;
-            this.targetSdk = targetSdk;
-        }
-    }
-
     /**
      * List of new permissions that have been added since 1.0.
      * NOTE: These must be declared in SDK version order, with permissions
@@ -290,34 +277,6 @@
     };
 
     /**
-     * List of permissions that have been split into more granular or dependent
-     * permissions.
-     * @hide
-     */
-    public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] =
-        new PackageParser.SplitPermissionInfo[] {
-            // 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 PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                    new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE },
-                    android.os.Build.VERSION_CODES.CUR_DEVELOPMENT+1),
-            new PackageParser.SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
-                    new String[] { android.Manifest.permission.READ_CALL_LOG },
-                    android.os.Build.VERSION_CODES.JELLY_BEAN),
-            new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS,
-                    new String[] { android.Manifest.permission.WRITE_CALL_LOG },
-                    android.os.Build.VERSION_CODES.JELLY_BEAN),
-            new PackageParser.SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION,
-                    new String[] { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION },
-                    android.os.Build.VERSION_CODES.P0),
-            new PackageParser.SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION,
-                    new String[] { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION },
-                    android.os.Build.VERSION_CODES.P0),
-    };
-
-    /**
      * @deprecated callers should move to explicitly passing around source path.
      */
     @Deprecated
@@ -493,10 +452,12 @@
         public final boolean use32bitAbi;
         public final boolean extractNativeLibs;
         public final boolean isolatedSplits;
+        public final boolean isSplitRequired;
 
         public ApkLite(String codePath, String packageName, String splitName,
                 boolean isFeatureSplit,
-                String configForSplit, String usesSplitName, int versionCode, int versionCodeMajor,
+                String configForSplit, String usesSplitName, boolean isSplitRequired,
+                int versionCode, int versionCodeMajor,
                 int revisionCode, int installLocation, List<VerifierInfo> verifiers,
                 SigningDetails signingDetails, boolean coreApp,
                 boolean debuggable, boolean multiArch, boolean use32bitAbi,
@@ -519,6 +480,7 @@
             this.use32bitAbi = use32bitAbi;
             this.extractNativeLibs = extractNativeLibs;
             this.isolatedSplits = isolatedSplits;
+            this.isSplitRequired = isSplitRequired;
         }
 
         public long getLongVersionCode() {
@@ -1736,6 +1698,7 @@
         boolean extractNativeLibs = true;
         boolean isolatedSplits = false;
         boolean isFeatureSplit = false;
+        boolean isSplitRequired = false;
         String configForSplit = null;
         String usesSplitName = null;
 
@@ -1758,6 +1721,8 @@
                 configForSplit = attrs.getAttributeValue(i);
             } else if (attr.equals("isFeatureSplit")) {
                 isFeatureSplit = attrs.getAttributeBooleanValue(i, false);
+            } else if (attr.equals("isSplitRequired")) {
+                isSplitRequired = attrs.getAttributeBooleanValue(i, false);
             }
         }
 
@@ -1813,8 +1778,8 @@
         }
 
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
-                configForSplit, usesSplitName, versionCode, versionCodeMajor, revisionCode,
-                installLocation, verifiers, signingDetails, coreApp, debuggable,
+                configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor,
+                revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable,
                 multiArch, use32bitAbi, extractNativeLibs, isolatedSplits);
     }
 
@@ -2474,16 +2439,18 @@
             Slog.i(TAG, implicitPerms.toString());
         }
 
-        final int NS = PackageParser.SPLIT_PERMISSIONS.length;
+
+        final int NS = PermissionManager.SPLIT_PERMISSIONS.length;
         for (int is=0; is<NS; is++) {
-            final PackageParser.SplitPermissionInfo spi
-                    = PackageParser.SPLIT_PERMISSIONS[is];
-            if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk
-                    || !pkg.requestedPermissions.contains(spi.rootPerm)) {
+            final PermissionManager.SplitPermissionInfo spi =
+                    PermissionManager.SPLIT_PERMISSIONS[is];
+            if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk()
+                    || !pkg.requestedPermissions.contains(spi.getRootPermission())) {
                 continue;
             }
-            for (int in=0; in<spi.newPerms.length; in++) {
-                final String perm = spi.newPerms[in];
+            final String[] newPerms = spi.getNewPermissions();
+            for (int in = 0; in < newPerms.length; in++) {
+                final String perm = newPerms[in];
                 if (!pkg.requestedPermissions.contains(perm)) {
                     pkg.requestedPermissions.add(perm);
                 }
@@ -5818,52 +5785,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) {
@@ -5877,17 +5824,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;
             }
         }
 
@@ -5989,7 +5933,7 @@
                     if (Signature.areEffectiveMatch(
                             oldDetails.signatures[0],
                             pastSigningCertificates[i])
-                            && pastSigningCertificatesFlags[i] == flags) {
+                            && pastSigningCertificates[i].getFlags() == flags) {
                         return true;
                     }
                 }
@@ -6039,7 +5983,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;
                         }
                     }
@@ -6123,7 +6067,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;
                         }
                     }
@@ -6160,7 +6104,6 @@
             dest.writeInt(this.signatureSchemeVersion);
             dest.writeArraySet(this.publicKeys);
             dest.writeTypedArray(this.pastSigningCertificates, flags);
-            dest.writeIntArray(this.pastSigningCertificatesFlags);
         }
 
         protected SigningDetails(Parcel in) {
@@ -6169,7 +6112,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>() {
@@ -6208,9 +6150,6 @@
             if (!Arrays.equals(pastSigningCertificates, that.pastSigningCertificates)) {
                 return false;
             }
-            if (!Arrays.equals(pastSigningCertificatesFlags, that.pastSigningCertificatesFlags)) {
-                return false;
-            }
 
             return true;
         }
@@ -6221,7 +6160,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;
         }
 
@@ -6232,7 +6170,6 @@
             private Signature[] mSignatures;
             private int mSignatureSchemeVersion = SignatureSchemeVersion.UNKNOWN;
             private Signature[] mPastSigningCertificates;
-            private int[] mPastSigningCertificatesFlags;
 
             @UnsupportedAppUsage
             public Builder() {
@@ -6259,34 +6196,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
@@ -6294,7 +6209,7 @@
                     throws CertificateException {
                 checkInvariants();
                 return new SigningDetails(mSignatures, mSignatureSchemeVersion,
-                        mPastSigningCertificates, mPastSigningCertificatesFlags);
+                        mPastSigningCertificates);
             }
         }
     }
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/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 121b432..799f8e5 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -46,6 +46,7 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.WindowConfiguration;
+import android.content.LocaleProto;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ActivityInfo.Config;
 import android.os.Build;
@@ -54,7 +55,9 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
+import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
+import android.util.proto.WireTypeMismatchException;
 import android.view.View;
 
 import com.android.internal.util.XmlUtils;
@@ -67,6 +70,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -1086,12 +1090,14 @@
     /**
      * Write to a protocol buffer output stream.
      * Protocol buffer message definition at {@link android.content.ConfigurationProto}
+     * Has the option to ignore fields that don't need to be persisted to disk.
      *
      * @param protoOutputStream Stream to write the Configuration object to.
      * @param fieldId           Field Id of the Configuration as defined in the parent message
+     * @param persisted         Note if this proto will be persisted to disk
      * @hide
      */
-    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
+    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted) {
         final long token = protoOutputStream.start(fieldId);
         protoOutputStream.write(FONT_SCALE, fontScale);
         protoOutputStream.write(MCC, mcc);
@@ -1113,13 +1119,137 @@
         protoOutputStream.write(SCREEN_HEIGHT_DP, screenHeightDp);
         protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp);
         protoOutputStream.write(DENSITY_DPI, densityDpi);
-        if (windowConfiguration != null) {
+        // For persistence, we do not care about window configuration
+        if (!persisted && windowConfiguration != null) {
             windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
         }
         protoOutputStream.end(token);
     }
 
     /**
+     * Write to a protocol buffer output stream.
+     * Protocol buffer message definition at {@link android.content.ConfigurationProto}
+     *
+     * @param protoOutputStream Stream to write the Configuration object to.
+     * @param fieldId           Field Id of the Configuration as defined in the parent message
+     * @hide
+     */
+    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
+        writeToProto(protoOutputStream, fieldId, false);
+    }
+
+    /**
+     * Read from a protocol buffer output stream.
+     * Protocol buffer message definition at {@link android.content.ConfigurationProto}
+     *
+     * @param protoInputStream Stream to read the Configuration object from.
+     * @param fieldId          Field Id of the Configuration as defined in the parent message
+     * @hide
+     */
+    public void readFromProto(ProtoInputStream protoInputStream, long fieldId) throws IOException {
+        final long token = protoInputStream.start(fieldId);
+        final List<Locale> list = new ArrayList();
+        try {
+            while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                switch (protoInputStream.getFieldNumber()) {
+                    case (int) FONT_SCALE:
+                        fontScale = protoInputStream.readFloat(FONT_SCALE);
+                        break;
+                    case (int) MCC:
+                        mcc = protoInputStream.readInt(MCC);
+                        break;
+                    case (int) MNC:
+                        mnc = protoInputStream.readInt(MNC);
+                        break;
+                    case (int) LOCALES:
+                        // Parse the Locale here to handle all the repeated Locales
+                        // The LocaleList will be created when the message is completed
+                        final long localeToken = protoInputStream.start(LOCALES);
+                        String language = "";
+                        String country = "";
+                        String variant = "";
+                        try {
+                            while (protoInputStream.nextField()
+                                    != ProtoInputStream.NO_MORE_FIELDS) {
+                                switch (protoInputStream.getFieldNumber()) {
+                                    case (int) LocaleProto.LANGUAGE:
+                                        language = protoInputStream.readString(
+                                                LocaleProto.LANGUAGE);
+                                        break;
+                                    case (int) LocaleProto.COUNTRY:
+                                        country = protoInputStream.readString(LocaleProto.COUNTRY);
+                                        break;
+                                    case (int) LocaleProto.VARIANT:
+                                        variant = protoInputStream.readString(LocaleProto.VARIANT);
+                                        break;
+                                }
+                            }
+                        } catch (WireTypeMismatchException wtme) {
+                            // rethrow for caller deal with
+                            throw wtme;
+                        } finally {
+                            protoInputStream.end(localeToken);
+                            list.add(new Locale(language, country, variant));
+                        }
+                        break;
+                    case (int) SCREEN_LAYOUT:
+                        screenLayout = protoInputStream.readInt(SCREEN_LAYOUT);
+                        break;
+                    case (int) COLOR_MODE:
+                        colorMode = protoInputStream.readInt(COLOR_MODE);
+                        break;
+                    case (int) TOUCHSCREEN:
+                        touchscreen = protoInputStream.readInt(TOUCHSCREEN);
+                        break;
+                    case (int) KEYBOARD:
+                        keyboard = protoInputStream.readInt(KEYBOARD);
+                        break;
+                    case (int) KEYBOARD_HIDDEN:
+                        keyboardHidden = protoInputStream.readInt(KEYBOARD_HIDDEN);
+                        break;
+                    case (int) HARD_KEYBOARD_HIDDEN:
+                        hardKeyboardHidden = protoInputStream.readInt(HARD_KEYBOARD_HIDDEN);
+                        break;
+                    case (int) NAVIGATION:
+                        navigation = protoInputStream.readInt(NAVIGATION);
+                        break;
+                    case (int) NAVIGATION_HIDDEN:
+                        navigationHidden = protoInputStream.readInt(NAVIGATION_HIDDEN);
+                        break;
+                    case (int) ORIENTATION:
+                        orientation = protoInputStream.readInt(ORIENTATION);
+                        break;
+                    case (int) UI_MODE:
+                        uiMode = protoInputStream.readInt(UI_MODE);
+                        break;
+                    case (int) SCREEN_WIDTH_DP:
+                        screenWidthDp = protoInputStream.readInt(SCREEN_WIDTH_DP);
+                        break;
+                    case (int) SCREEN_HEIGHT_DP:
+                        screenHeightDp = protoInputStream.readInt(SCREEN_HEIGHT_DP);
+                        break;
+                    case (int) SMALLEST_SCREEN_WIDTH_DP:
+                        smallestScreenWidthDp = protoInputStream.readInt(SMALLEST_SCREEN_WIDTH_DP);
+                        break;
+                    case (int) DENSITY_DPI:
+                        densityDpi = protoInputStream.readInt(DENSITY_DPI);
+                        break;
+                    case (int) WINDOW_CONFIGURATION:
+                        windowConfiguration.readFromProto(protoInputStream, WINDOW_CONFIGURATION);
+                        break;
+                }
+            }
+        } finally {
+            // Let caller handle any exceptions
+            if (list.size() > 0) {
+                //Create the LocaleList from the collected Locales
+                setLocales(new LocaleList(list.toArray(new Locale[list.size()])));
+            }
+            protoInputStream.end(token);
+        }
+    }
+
+    /**
      * Write full {@link android.content.ResourcesConfigurationProto} to protocol buffer output
      * stream.
      *
diff --git a/core/java/android/content/res/package.html b/core/java/android/content/res/package.html
index 3d0bac1..3970b16 100644
--- a/core/java/android/content/res/package.html
+++ b/core/java/android/content/res/package.html
@@ -1,7 +1,7 @@
 <HTML>
 <BODY>
 <p>Contains classes for accessing application resources,
-such as raw asset files, colors, drawables, media or other other files
+such as raw asset files, colors, drawables, media, or other files
 in the package, plus important device configuration details
 (orientation, input types, etc.) that affect how the application may behave.</p>
 
@@ -9,4 +9,4 @@
 href="{@docRoot}guide/topics/resources/index.html">Application Resources</a> guide.</p>
 {@more}
 </BODY>
-</HTML>
\ No newline at end of file
+</HTML>
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 01557c5..eb5c720 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -649,7 +649,7 @@
      * successful so far. Do not call setTransactionSuccessful before calling this. When this
      * returns a new transaction will have been created but not marked as successful.
      * @return true if the transaction was yielded
-     * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock
+     * @deprecated if the db is locked more than once (because of nested transactions) then the lock
      *   will not be yielded. Use yieldIfContendedSafely instead.
      */
     @Deprecated
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 94f2ac0..0d7b695 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -31,7 +31,7 @@
  * Android may use a newer version of the model.
  */
 public class GeomagneticField {
-    // The magnetic field at a given point, in nonoteslas in geodetic
+    // The magnetic field at a given point, in nanoteslas in geodetic
     // coordinates.
     private float mX;
     private float mY;
@@ -278,7 +278,7 @@
     }
 
     /**
-     * @return  Horizontal component of the field strength in nonoteslas.
+     * @return  Horizontal component of the field strength in nanoteslas.
      */
     public float getHorizontalStrength() {
         return (float) Math.hypot(mX, mY);
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
new file mode 100644
index 0000000..1d40001
--- /dev/null
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.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;
+
+    /**
+     * @hide
+     * @param context
+     * @param service
+     */
+    public BiometricManager(Context context, IBiometricService service) {
+        mContext = context;
+        mService = service;
+    }
+
+    /**
+     * 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 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 @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 1cca27d..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");
@@ -225,7 +242,7 @@
 
     private final IBinder mToken = new Binder();
     private final Context mContext;
-    private final IBiometricPromptService mService;
+    private final IBiometricService mService;
     private final Bundle mBundle;
     private final ButtonInfo mPositiveButtonInfo;
     private final ButtonInfo mNegativeButtonInfo;
@@ -250,8 +267,8 @@
         }
     };
 
-    IBiometricPromptServiceReceiver mBiometricPromptServiceReceiver =
-            new IBiometricPromptServiceReceiver.Stub() {
+    IBiometricServiceReceiver mBiometricServiceReceiver =
+            new IBiometricServiceReceiver.Stub() {
 
         @Override
         public void onAuthenticationSucceeded(long deviceId) throws RemoteException {
@@ -290,8 +307,8 @@
         mBundle = bundle;
         mPositiveButtonInfo = positiveButtonInfo;
         mNegativeButtonInfo = negativeButtonInfo;
-        mService = IBiometricPromptService.Stub.asInterface(
-                ServiceManager.getService(Context.BIOMETRIC_PROMPT_SERVICE));
+        mService = IBiometricService.Stub.asInterface(
+                ServiceManager.getService(Context.BIOMETRIC_SERVICE));
     }
 
     /**
@@ -348,7 +365,6 @@
          * @hide
          */
         public AuthenticationResult(CryptoObject crypto) {
-            // For compatibility, this extends from common base class as FingerprintManager does.
             // Identifier and userId is not used for BiometricPrompt.
             super(crypto, null /* identifier */, 0 /* userId */);
         }
@@ -410,8 +426,8 @@
     }
 
     /**
-     * This call warms up the fingerprint hardware, displays a system-provided dialog, and starts
-     * scanning for a fingerprint. It terminates when {@link
+     * This call warms up the biometric hardware, displays a system-provided dialog, and starts
+     * scanning for a biometric. It terminates when {@link
      * AuthenticationCallback#onAuthenticationError(int, CharSequence)} is called, when {@link
      * AuthenticationCallback#onAuthenticationSucceeded( AuthenticationResult)}, or when the user
      * dismisses the system-provided dialog, at which point the crypto object becomes invalid. This
@@ -453,8 +469,8 @@
     }
 
     /**
-     * This call warms up the fingerprint hardware, displays a system-provided dialog, and starts
-     * scanning for a fingerprint. It terminates when {@link
+     * This call warms up the biometric hardware, displays a system-provided dialog, and starts
+     * scanning for a biometric. It terminates when {@link
      * AuthenticationCallback#onAuthenticationError(int, CharSequence)} is called, when {@link
      * AuthenticationCallback#onAuthenticationSucceeded( AuthenticationResult)} is called, or when
      * the user dismisses the system-provided dialog.  This operation can be canceled by using the
@@ -516,7 +532,7 @@
             mAuthenticationCallback = callback;
             final long sessionId = crypto != null ? crypto.getOpId() : 0;
             mService.authenticate(mToken, sessionId, mContext.getUserId(),
-                    mBiometricPromptServiceReceiver, 0 /* flags */, mContext.getOpPackageName(),
+                    mBiometricServiceReceiver, 0 /* flags */, mContext.getOpPackageName(),
                     mBundle, mDialogReceiver);
         } catch (RemoteException e) {
             Log.e(TAG, "Remote exception while authenticating", e);
diff --git a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
new file mode 100644
index 0000000..d22e7e2
--- /dev/null
+++ b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
@@ -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.
+ */
+
+package android.hardware.biometrics;
+
+import android.hardware.biometrics.BiometricSourceType;
+
+/**
+ * @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/IBiometricPromptService.aidl b/core/java/android/hardware/biometrics/IBiometricPromptService.aidl
deleted file mode 100644
index 2c93579..0000000
--- a/core/java/android/hardware/biometrics/IBiometricPromptService.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.biometrics;
-
-import android.os.Bundle;
-import android.hardware.biometrics.IBiometricPromptReceiver;
-import android.hardware.biometrics.IBiometricPromptServiceReceiver;
-
-/**
- * Communication channel from BiometricPrompt to BiometricPromptService. The interface does not
- * expose specific biometric modalities. The system will use the default biometric for apps. On
- * devices with more than one, the choice is dictated by user preference in Settings.
- * @hide
- */
-interface IBiometricPromptService {
-    // Requests authentication. The service choose the appropriate biometric to use, and show
-    // the corresponding BiometricDialog.
-    void authenticate(IBinder token, long sessionId, int userId,
-            IBiometricPromptServiceReceiver receiver, int flags, String opPackageName,
-            in Bundle bundle, IBiometricPromptReceiver dialogReceiver);
-
-    // Cancel authentication for the given sessionId
-    void cancelAuthentication(IBinder token, String opPackageName);
-}
\ No newline at end of file
diff --git a/core/java/android/hardware/biometrics/IBiometricPromptServiceReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricPromptServiceReceiver.aidl
deleted file mode 100644
index 1ef6c52..0000000
--- a/core/java/android/hardware/biometrics/IBiometricPromptServiceReceiver.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.biometrics;
-
-import android.hardware.biometrics.BiometricSourceType;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-/**
- * Communication channel from the BiometricPromptService back to BiometricPrompt.
- * @hide
- */
-oneway interface IBiometricPromptServiceReceiver {
-    void onAuthenticationSucceeded(long deviceId);
-    void onAuthenticationFailed(long deviceId);
-    void onError(long deviceId, int error, String message);
-    void onAcquired(long deviceId, int acquiredInfo, String message);
-}
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
new file mode 100644
index 0000000..e17feff
--- /dev/null
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics;
+
+import android.os.Bundle;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
+import android.hardware.biometrics.IBiometricPromptReceiver;
+import android.hardware.biometrics.IBiometricServiceReceiver;
+
+/**
+ * Communication channel from BiometricPrompt and BiometricManager to BiometricService. The
+ * interface does not expose specific biometric modalities. The system will use the default
+ * biometric for apps. On devices with more than one, the choice is dictated by user preference in
+ * Settings.
+ * @hide
+ */
+interface IBiometricService {
+    // Requests authentication. The service choose the appropriate biometric to use, and show
+    // the corresponding BiometricDialog.
+    void authenticate(IBinder token, long sessionId, int userId,
+            IBiometricServiceReceiver receiver, int flags, String opPackageName,
+            in Bundle bundle, IBiometricPromptReceiver dialogReceiver);
+
+    // Cancel authentication for the given sessionId
+    void cancelAuthentication(IBinder token, String opPackageName);
+
+    // 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
new file mode 100644
index 0000000..a6e3696
--- /dev/null
+++ b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.biometrics;
+
+/**
+ * Communication channel from the BiometricService back to BiometricPrompt.
+ * @hide
+ */
+oneway interface IBiometricServiceReceiver {
+    void onAuthenticationSucceeded(long deviceId);
+    void onAuthenticationFailed(long deviceId);
+    void onError(long deviceId, int error, String message);
+    void onAcquired(long deviceId, int acquiredInfo, String message);
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index d967fba..7810e6c 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -1889,7 +1889,7 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 CameraDeviceImpl.this.mDeviceExecutor.execute(obtainRunnable(
-                            CameraDeviceCallbacks::notifyError, this, code));
+                            CameraDeviceCallbacks::notifyError, this, code).recycleOnUse());
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/core/java/android/hardware/camera2/utils/CloseableLock.java b/core/java/android/hardware/camera2/utils/CloseableLock.java
index 9ac89c8..3b8beac 100644
--- a/core/java/android/hardware/camera2/utils/CloseableLock.java
+++ b/core/java/android/hardware/camera2/utils/CloseableLock.java
@@ -290,7 +290,7 @@
     /**
      * Release a single lock that was acquired.
      *
-     * <p>Any other other that is blocked and trying to acquire a lock will get a chance
+     * <p>Any other thread that is blocked and trying to acquire a lock will get a chance
      * to acquire the lock.</p>
      *
      * @throws IllegalStateException if no locks were acquired, or if the lock was already closed
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index e8fb287..09113e5 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;
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 20e0116..536c4a5 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -244,17 +244,17 @@
     }
 
     /**
-     * Requests a pre-enrollment auth token to tie enrollment to the confirmation of
+     * Requests an auth token to tie sensitive operations to the confirmation of
      * existing device credentials (e.g. pin/pattern/password).
      *
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
-    public long preEnroll() {
+    public long generateChallenge() {
         long result = 0;
         if (mService != null) {
             try {
-                result = mService.preEnroll(mToken);
+                result = mService.generateChallenge(mToken);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -263,16 +263,46 @@
     }
 
     /**
-     * Finishes enrollment and cancels the current auth token.
+     * Invalidates the current auth token.
      *
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
-    public int postEnroll() {
+    public int revokeChallenge() {
         int result = 0;
         if (mService != null) {
             try {
-                result = mService.postEnroll(mToken);
+                result = mService.revokeChallenge(mToken);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(MANAGE_BIOMETRIC)
+    public void setRequireAttention(boolean requireAttention, byte[] token) {
+        if (mService != null) {
+            try {
+                mService.setRequireAttention(requireAttention, token);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(MANAGE_BIOMETRIC)
+    public boolean getRequireAttention(byte[] token) {
+        boolean result = true;
+        if (mService != null) {
+            try {
+                mService.getRequireAttention(token);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -287,6 +317,7 @@
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
+    @Override
     public void setActiveUser(int userId) {
         if (mService != null) {
             try {
@@ -378,6 +409,7 @@
     @RequiresPermission(allOf = {
             USE_BIOMETRIC_INTERNAL,
             INTERACT_ACROSS_USERS})
+    @Override
     public boolean hasEnrolledTemplates(int userId) {
         if (mService != null) {
             try {
@@ -521,16 +553,16 @@
      */
     public static String getErrorString(Context context, int errMsg, int vendorCode) {
         switch (errMsg) {
-            case FACE_ERROR_HW_UNAVAILABLE:
-                return context.getString(
-                        com.android.internal.R.string.face_error_hw_not_available);
             case FACE_ERROR_UNABLE_TO_PROCESS:
                 return context.getString(
                         com.android.internal.R.string.face_error_unable_to_process);
-            case FACE_ERROR_TIMEOUT:
-                return context.getString(com.android.internal.R.string.face_error_timeout);
+            case FACE_ERROR_HW_UNAVAILABLE:
+                return context.getString(
+                        com.android.internal.R.string.face_error_hw_not_available);
             case FACE_ERROR_NO_SPACE:
                 return context.getString(com.android.internal.R.string.face_error_no_space);
+            case FACE_ERROR_TIMEOUT:
+                return context.getString(com.android.internal.R.string.face_error_timeout);
             case FACE_ERROR_CANCELED:
                 return context.getString(com.android.internal.R.string.face_error_canceled);
             case FACE_ERROR_LOCKOUT:
@@ -538,6 +570,8 @@
             case FACE_ERROR_LOCKOUT_PERMANENT:
                 return context.getString(
                         com.android.internal.R.string.face_error_lockout_permanent);
+            case FACE_ERROR_USER_CANCELED:
+                return context.getString(com.android.internal.R.string.face_error_user_canceled);
             case FACE_ERROR_NOT_ENROLLED:
                 return context.getString(com.android.internal.R.string.face_error_not_enrolled);
             case FACE_ERROR_HW_NOT_PRESENT:
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index dd995c9..6681bd7 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -17,7 +17,7 @@
 
 import android.os.Bundle;
 import android.hardware.biometrics.IBiometricPromptReceiver;
-import android.hardware.biometrics.IBiometricPromptServiceReceiver;
+import android.hardware.biometrics.IBiometricServiceReceiver;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
 import android.hardware.face.IFaceServiceReceiver;
 import android.hardware.face.Face;
@@ -34,8 +34,8 @@
 
     // This method invokes the BiometricDialog. The arguments are almost the same as above,
     // but should only be called from (BiometricPromptService).
-    void authenticateFromService(IBinder token, long sessionId, int userId,
-            IBiometricPromptServiceReceiver receiver, int flags, String opPackageName,
+    void authenticateFromService(boolean requireConfirmation, IBinder token, long sessionId,
+            int userId, IBiometricServiceReceiver receiver, int flags, String opPackageName,
             in Bundle bundle, IBiometricPromptReceiver dialogReceiver,
             int callingUid, int callingPid, int callingUserId);
 
@@ -66,10 +66,10 @@
     boolean isHardwareDetected(long deviceId, String opPackageName);
 
     // Get a pre-enrollment authentication token
-    long preEnroll(IBinder token);
+    long generateChallenge(IBinder token);
 
     // Finish an enrollment sequence and invalidate the authentication token
-    int postEnroll(IBinder token);
+    int revokeChallenge(IBinder token);
 
     // Determine if a user has at least one enrolled face
     boolean hasEnrolledFaces(int userId, String opPackageName);
@@ -94,4 +94,8 @@
 
     // Enumerate all faces
     void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver);
+
+    int setRequireAttention(boolean requireAttention, in byte [] token);
+
+    boolean getRequireAttention(in byte [] token);
 }
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/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 2b2c0b7..2662a11 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -17,7 +17,7 @@
 
 import android.os.Bundle;
 import android.hardware.biometrics.IBiometricPromptReceiver;
-import android.hardware.biometrics.IBiometricPromptServiceReceiver;
+import android.hardware.biometrics.IBiometricServiceReceiver;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
 import android.hardware.fingerprint.IFingerprintClientActiveCallback;
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
@@ -40,7 +40,7 @@
     // called from BiometricPromptService. The additional uid, pid, userId arguments should be
     // determined by BiometricPromptService.
     void authenticateFromService(IBinder token, long sessionId, int userId,
-            IBiometricPromptServiceReceiver receiver, int flags, String opPackageName,
+            IBiometricServiceReceiver receiver, int flags, String opPackageName,
             in Bundle bundle, IBiometricPromptReceiver dialogReceiver,
             int callingUid, int callingPid, int callingUserId);
 
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/ContextHubBroadcastReceiver.java b/core/java/android/hardware/location/ContextHubBroadcastReceiver.java
new file mode 100644
index 0000000..e0cc8b7
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubBroadcastReceiver.java
@@ -0,0 +1,102 @@
+/*
+ * 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.hardware.location;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+
+/**
+ * A BroadcastReceiver that can be used with the Context Hub Service notifications.
+ *
+ * @hide
+ */
+public class ContextHubBroadcastReceiver extends BroadcastReceiver {
+    // The context at which this receiver operates in
+    private Context mContext;
+
+    // The handler to post callbacks to when receiving Context Hub Service intents
+    private Handler mHandler;
+
+    // The callback to be invoked when receiving Context Hub Service intents
+    private ContextHubClientCallback mCallback;
+
+    // The string to use as the broadcast action for this receiver
+    private String mAction;
+
+    // True when this receiver is registered to receive Intents, false otherwise
+    private boolean mRegistered = false;
+
+    public ContextHubBroadcastReceiver(Context context, Handler handler,
+                                       ContextHubClientCallback callback, String tag) {
+        mContext = context;
+        mHandler = handler;
+        mCallback = callback;
+        mAction = tag;
+    }
+
+    /**
+     * Registers this receiver to receive Intents from the Context Hub Service. This method must
+     * only be invoked when the receiver is not registered.
+     *
+     * @throws IllegalStateException if the receiver is already registered
+     */
+    public void register() throws IllegalStateException {
+        if (mRegistered) {
+            throw new IllegalStateException(
+                "Cannot register ContextHubBroadcastReceiver multiple times");
+        }
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(mAction);
+        mContext.registerReceiver(this, intentFilter, null /* broadcastPermission */, mHandler);
+        mRegistered = true;
+    }
+
+    /**
+     * Unregisters this receiver. This method must only be invoked if {@link #register()} is
+     * previously invoked.
+     *
+     * @throws IllegalStateException if the receiver is not yet registered
+     */
+    public void unregister() throws IllegalStateException {
+        if (!mRegistered) {
+            throw new IllegalStateException(
+                "Cannot unregister ContextHubBroadcastReceiver when not registered");
+        }
+        mContext.unregisterReceiver(this);
+        mRegistered = false;
+    }
+
+    /**
+     * Creates a new PendingIntent associated with this receiver.
+     *
+     * @param flags the flags {@link PendingIntent.Flags} to use for the PendingIntent
+     *
+     * @return a PendingIntent to receive notifications for this receiver
+     */
+    public PendingIntent getPendingIntent(@PendingIntent.Flags int flags) {
+        return PendingIntent.getBroadcast(
+            mContext, 0 /* requestCode */, new Intent(mAction), flags);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // TODO: Implement this
+    }
+}
diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java
index 2335203..917644d 100644
--- a/core/java/android/hardware/location/ContextHubClient.java
+++ b/core/java/android/hardware/location/ContextHubClient.java
@@ -18,6 +18,7 @@
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.app.PendingIntent;
 import android.os.RemoteException;
 
 import com.android.internal.util.Preconditions;
@@ -100,6 +101,57 @@
     }
 
     /**
+     * Registers to receive persistent intents for a given nanoapp.
+     *
+     * 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.
+     *
+     * When the intent is received, this client can be recreated through
+     * {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo,
+     * ContextHubClientCallback, Exectutor)}. When recreated, the client can be treated as the
+     * same endpoint entity from a nanoapp's perspective, and can be continued to be used to send
+     * messages even if the original process has exited.
+     *
+     * Intents will be delivered until it is unregistered through
+     * {@link #unregisterIntent(PendingIntent)}. Note that the registration of this client will
+     * continued to be maintained at the Context Hub Service until
+     * {@link #unregisterIntent(PendingIntent)} is called for registered intents.
+     *
+     * See {@link ContextHubBroadcastReceiver} for a helper class to generate the
+     * {@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
+     * @return true on success, false otherwise
+     *
+     * @hide
+     */
+    public boolean registerIntent(@NonNull PendingIntent intent, long nanoAppId) {
+        // TODO: Implement this
+        return false;
+    }
+
+    /**
+     * Unregisters an intent previously registered via {@link #registerIntent(PendingIntent, long)}.
+     * If this intent has not been registered for this client, this method returns false.
+     *
+     * @return true on success, false otherwise
+     *
+     * @hide
+     */
+    public boolean unregisterIntent(@NonNull PendingIntent intent) {
+        // TODO: Implement this
+        return false;
+    }
+
+    /**
      * Sends a message to a nanoapp through the Context Hub Service.
      *
      * This function returns RESULT_SUCCESS if the message has reached the HAL, but
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 12d0531..36f3586 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -16,12 +16,14 @@
 package android.hardware.location;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.PendingIntent;
 import android.content.Context;
 import android.os.Handler;
 import android.os.HandlerExecutor;
@@ -33,6 +35,8 @@
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -49,6 +53,111 @@
 public final class ContextHubManager {
     private static final String TAG = "ContextHubManager";
 
+    /**
+     * An extra of type {@link ContextHubInfo} describing the source of the event.
+     *
+     * @hide
+     */
+    public static final String EXTRA_CONTEXT_HUB_INFO =
+            "android.hardware.location.extra.CONTEXT_HUB_INFO";
+
+    /**
+     * An extra of type {@link ContextHubManager.Event} describing the event type.
+     *
+     * @hide
+     */
+    public static final String EXTRA_EVENT_TYPE = "android.hardware.location.extra.EVENT_TYPE";
+
+    /**
+     * An extra of type long describing the ID of the nanoapp an event is for.
+     *
+     * @hide
+     */
+    public static final String EXTRA_NANOAPP_ID = "android.location.hardware.extra.NANOAPP_ID";
+
+    /**
+     * An extra of type int describing the nanoapp-specific abort code.
+     *
+     * @hide
+     */
+    public static final String EXTRA_NANOAPP_ABORT_CODE =
+            "android.location.hardware.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";
+
+    /**
+     * Constants describing the type of events from a Context Hub.
+     * {@hide}
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "EVENT_" }, value = {
+        EVENT_NANOAPP_LOADED,
+        EVENT_NANOAPP_UNLOADED,
+        EVENT_NANOAPP_ENABLED,
+        EVENT_NANOAPP_DISABLED,
+        EVENT_NANOAPP_ABORTED,
+        EVENT_NANOAPP_MESSAGE,
+        EVENT_HUB_RESET,
+    })
+    public @interface Event { }
+
+    /**
+     * An event describing that a nanoapp has been loaded. Contains the EXTRA_NANOAPP_ID extra.
+     *
+     * @hide
+     */
+    public static final int EVENT_NANOAPP_LOADED = 0;
+
+    /**
+     * An event describing that a nanoapp has been unloaded. Contains the EXTRA_NANOAPP_ID extra.
+     *
+     * @hide
+     */
+    public static final int EVENT_NANOAPP_UNLOADED = 1;
+
+    /**
+     * An event describing that a nanoapp has been enabled. Contains the EXTRA_NANOAPP_ID extra.
+     *
+     * @hide
+     */
+    public static final int EVENT_NANOAPP_ENABLED = 2;
+
+    /**
+     * An event describing that a nanoapp has been disabled. Contains the EXTRA_NANOAPP_ID extra.
+     *
+     * @hide
+     */
+    public static final int EVENT_NANOAPP_DISABLED = 3;
+
+    /**
+     * An event describing that a nanoapp has aborted. Contains the EXTRA_NANOAPP_ID and
+     * EXTRA_NANOAPP_ABORT_CODE extras.
+     *
+     * @hide
+     */
+    public static final int EVENT_NANOAPP_ABORTED = 4;
+
+    /**
+     * An event containing a message sent from a nanoapp. Contains the EXTRA_NANOAPP_ID and
+     * EXTRA_NANOAPP_MESSAGE extras.
+     *
+     * @hide
+     */
+    public static final int EVENT_NANOAPP_MESSAGE = 5;
+
+    /**
+     * An event describing that the Context Hub has reset.
+     *
+     * @hide
+     */
+    public static final int EVENT_HUB_RESET = 6;
+
+
     private final Looper mMainLooper;
     private final IContextHubService mService;
     private Callback mCallback;
@@ -682,6 +791,57 @@
     }
 
     /**
+     * Creates a ContextHubClient based on an Intent received by the Context Hub Service.
+     *
+     * This method is intended to be used after receiving an Intent received as a result of
+     * {@link ContextHubClient.registerIntent(PendingIntent, long)}, and must have been created
+     * 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
+     * @return the registered client object
+     *
+     * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent
+     *                                  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
+     *
+     * @hide
+     */
+    @NonNull public ContextHubClient createClient(
+            @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo,
+            @NonNull ContextHubClientCallback callback,
+            @NonNull @CallbackExecutor Executor executor) {
+        // TODO: Implement this
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Equivalent to {@link #createClient(Intent, 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
+     * @return the registered client object
+     *
+     * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent
+     *                                  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
+     *
+     * @hide
+     */
+    @NonNull public ContextHubClient createClient(
+            @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo,
+            @NonNull ContextHubClientCallback callback) {
+        return createClient(intent, hubInfo, callback, new HandlerExecutor(Handler.getMain()));
+    }
+
+    /**
      * Unregister a callback for receive messages from the context hub.
      *
      * @see Callback
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/usb/IUsbSerialReader.aidl b/core/java/android/hardware/usb/IUsbSerialReader.aidl
new file mode 100644
index 0000000..787d5cd
--- /dev/null
+++ b/core/java/android/hardware/usb/IUsbSerialReader.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+/** @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/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 34fa5b6..097a3e3 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -85,6 +85,7 @@
 import com.android.internal.inputmethod.IInputContentUriToken;
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -409,14 +410,6 @@
     @GuardedBy("mLock")
     private boolean mNotifyUserActionSent;
 
-    /**
-     * {@code true} when the previous IME had non-empty inset at the bottom of the screen and we
-     * have not shown our own window yet.  In this situation, the previous inset continues to be
-     * shown as an empty region until it is explicitly updated. Basically we can trigger the update
-     * by calling 1) {@code mWindow.show()} or 2) {@link #clearInsetOfPreviousIme()}.
-     */
-    boolean mShouldClearInsetOfPreviousIme;
-
     @UnsupportedAppUsage
     final Insets mTmpInsets = new Insets();
     final int[] mTmpLocation = new int[2];
@@ -465,7 +458,7 @@
         public final void initializeInternal(IBinder token, int displayId,
                 IInputMethodPrivilegedOperations privilegedOperations) {
             mPrivOps.set(privilegedOperations);
-            mImm.registerInputMethodPrivOps(token, mPrivOps);
+            InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
             updateInputMethodDisplay(displayId);
             attachToken(token);
         }
@@ -580,7 +573,6 @@
             mShowInputFlags = 0;
             mShowInputRequested = false;
             doHideWindow();
-            clearInsetOfPreviousIme();
             if (resultReceiver != null) {
                 resultReceiver.send(wasVis != isInputViewShown()
                         ? InputMethodManager.RESULT_HIDDEN
@@ -600,7 +592,6 @@
             if (dispatchOnShowInputRequested(flags, false)) {
                 showWindow(true);
             }
-            clearInsetOfPreviousIme();
             // If user uses hard keyboard, IME button should always be shown.
             setImeWindowStatus(mapToImeWindowStatus(isInputViewShown()), mBackDisposition);
 
@@ -945,9 +936,6 @@
         super.onCreate();
         mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
         mSettingsObserver = SettingsObserver.createAndRegister(this);
-        // If the previous IME has occupied non-empty inset in the screen, we need to decide whether
-        // we continue to use the same size of the inset or update it
-        mShouldClearInsetOfPreviousIme = (mImm.getInputMethodWindowVisibleHeight() > 0);
         // TODO(b/111364446) Need to address context lifecycle issue if need to re-create
         // for update resources & configuration correctly when show soft input
         // in non-default display.
@@ -1031,7 +1019,7 @@
         if (mToken != null) {
             // This is completely optional, but allows us to show more explicit error messages
             // when IME developers are doing something unsupported.
-            mImm.unregisterInputMethodPrivOps(mToken);
+            InputMethodPrivilegedOperationsRegistry.remove(mToken);
         }
     }
 
@@ -1881,9 +1869,6 @@
             if (DEBUG) Log.v(TAG, "showWindow: showing!");
             onWindowShown();
             mWindow.show();
-            // Put here rather than in onWindowShown() in case people forget to call
-            // super.onWindowShown().
-            mShouldClearInsetOfPreviousIme = false;
         }
     }
 
@@ -1933,32 +1918,6 @@
     }
 
     /**
-     * Reset the inset occupied the previous IME when and only when
-     * {@link #mShouldClearInsetOfPreviousIme} is {@code true}.
-     */
-    private void clearInsetOfPreviousIme() {
-        if (DEBUG) Log.v(TAG, "clearInsetOfPreviousIme() "
-                + " mShouldClearInsetOfPreviousIme=" + mShouldClearInsetOfPreviousIme);
-        if (!mShouldClearInsetOfPreviousIme) return;
-
-        clearLastInputMethodWindowForTransition();
-        mShouldClearInsetOfPreviousIme = false;
-    }
-
-    /**
-     * Tells the system that the IME decided to not show a window and the system no longer needs to
-     * use the previous IME's inset.
-     *
-     * <p>Caveat: {@link android.inputmethodservice.InputMethodService#clearInsetOfPreviousIme()}
-     * is the only expected caller of this method.  Do not depend on this anywhere else.</p>
-     *
-     * <p>TODO: We probably need to reconsider how IME should be handled.</p>
-     */
-    private void clearLastInputMethodWindowForTransition() {
-        mPrivOps.clearLastInputMethodWindowForTransition();
-    }
-
-    /**
      * Called when a new client has bound to the input method.  This
      * may be followed by a series of {@link #onStartInput(EditorInfo, boolean)}
      * and {@link #onFinishInput()} calls as the user navigates through its
@@ -2136,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) {
@@ -2203,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() {
@@ -2844,18 +2803,22 @@
     }
 
     /**
-     * @return The recommended height of the input method window.
-     * An IME author can get the last input method's height as the recommended height
-     * by calling this in
-     * {@link android.inputmethodservice.InputMethodService#onStartInputView(EditorInfo, boolean)}.
-     * If you don't need to use a predefined fixed height, you can avoid the window-resizing of IME
-     * switching by using this value as a visible inset height. It's efficient for the smooth
-     * transition between different IMEs. However, note that this may return 0 (or possibly
-     * unexpectedly low height). You should thus avoid relying on the return value of this method
-     * all the time. Please make sure to use a reasonable height for the IME.
+     * Aimed to return the previous input method's {@link Insets#contentTopInsets}, but its actual
+     * semantics has never been well defined.
+     *
+     * <p>Note that the previous document clearly mentioned that this method could return {@code 0}
+     * at any time for whatever reason.  Now this method is just always returning {@code 0}.</p>
+     *
+     * @return on Android {@link android.os.Build.VERSION_CODES#Q} and later devices this method
+     *         always returns {@code 0}
+     * @deprecated the actual behavior of this method has never been well defined.  You cannot use
+     *             this method in a reliable and predictable way
      */
+    @Deprecated
     public int getInputMethodWindowRecommendedHeight() {
-        return mImm.getInputMethodWindowVisibleHeight();
+        Log.w(TAG, "getInputMethodWindowRecommendedHeight() is deprecated and now always returns 0."
+                + " Do not use this method.");
+        return 0;
     }
 
     /**
@@ -2979,7 +2942,6 @@
                 + " visibleTopInsets=" + mTmpInsets.visibleTopInsets
                 + " touchableInsets=" + mTmpInsets.touchableInsets
                 + " touchableRegion=" + mTmpInsets.touchableRegion);
-        p.println(" mShouldClearInsetOfPreviousIme=" + mShouldClearInsetOfPreviousIme);
         p.println(" mSettingsObserver=" + mSettingsObserver);
     }
 }
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/ConnectionInfo.aidl b/core/java/android/net/ConnectionInfo.aidl
new file mode 100644
index 0000000..07faf8b
--- /dev/null
+++ b/core/java/android/net/ConnectionInfo.aidl
@@ -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.
+*/
+
+package android.net;
+
+parcelable ConnectionInfo;
diff --git a/core/java/android/net/ConnectionInfo.java b/core/java/android/net/ConnectionInfo.java
new file mode 100644
index 0000000..58d0e05
--- /dev/null
+++ b/core/java/android/net/ConnectionInfo.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Describe a network connection including local and remote address/port of a connection and the
+ * transport protocol.
+ *
+ * @hide
+ */
+public final class ConnectionInfo implements Parcelable {
+    public final int protocol;
+    public final InetSocketAddress local;
+    public final InetSocketAddress remote;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public ConnectionInfo(int protocol, InetSocketAddress local, InetSocketAddress remote) {
+        this.protocol = protocol;
+        this.local = local;
+        this.remote = remote;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(protocol);
+        out.writeByteArray(local.getAddress().getAddress());
+        out.writeInt(local.getPort());
+        out.writeByteArray(remote.getAddress().getAddress());
+        out.writeInt(remote.getPort());
+    }
+
+    public static final Creator<ConnectionInfo> CREATOR = new Creator<ConnectionInfo>() {
+        public ConnectionInfo createFromParcel(Parcel in) {
+            int protocol = in.readInt();
+            InetAddress localAddress;
+            try {
+                localAddress = InetAddress.getByAddress(in.createByteArray());
+            } catch (UnknownHostException e) {
+                throw new IllegalArgumentException("Invalid InetAddress");
+            }
+            int localPort = in.readInt();
+            InetAddress remoteAddress;
+            try {
+                remoteAddress = InetAddress.getByAddress(in.createByteArray());
+            } catch (UnknownHostException e) {
+                throw new IllegalArgumentException("Invalid InetAddress");
+            }
+            int remotePort = in.readInt();
+            InetSocketAddress local = new InetSocketAddress(localAddress, localPort);
+            InetSocketAddress remote = new InetSocketAddress(remoteAddress, remotePort);
+            return new ConnectionInfo(protocol, local, remote);
+        }
+
+        public ConnectionInfo[] newArray(int size) {
+            return new ConnectionInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ce18796..8333b81 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -26,7 +26,6 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
@@ -59,6 +58,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -3800,8 +3800,9 @@
 
     private void unsupportedStartingFrom(int version) {
         if (Process.myUid() == Process.SYSTEM_UID) {
-            // The getApplicationInfo() call we make below is not supported in system context, and
-            // we want to allow the system to use these APIs anyway.
+            // The getApplicationInfo() call we make below is not supported in system context. Let
+            // the call through here, and rely on the fact that ConnectivityService will refuse to
+            // allow the system to use these APIs anyway.
             return;
         }
 
@@ -3818,11 +3819,6 @@
     // functions by accessing ConnectivityService directly. However, it should be clear that doing
     // so is unsupported and may break in the future. http://b/22728205
     private void checkLegacyRoutingApiAccess() {
-        if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS")
-                == PackageManager.PERMISSION_GRANTED) {
-            return;
-        }
-
         unsupportedStartingFrom(VERSION_CODES.M);
     }
 
@@ -3930,4 +3926,26 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Returns the {@code uid} of the owner of a network connection.
+     *
+     * @param protocol The protocol of the connection. Only {@code IPPROTO_TCP} and
+     * {@code IPPROTO_UDP} currently supported.
+     * @param local The local {@link InetSocketAddress} of a connection.
+     * @param remote The remote {@link InetSocketAddress} of a connection.
+     *
+     * @return {@code uid} if the connection is found and the app has permission to observe it
+     * (e.g., if it is associated with the calling VPN app's tunnel) or
+     * {@link android.os.Process#INVALID_UID} if the connection is not found.
+     */
+    public int getConnectionOwnerUid(int protocol, InetSocketAddress local,
+                                     InetSocketAddress remote) {
+        ConnectionInfo connectionInfo = new ConnectionInfo(protocol, local, remote);
+        try {
+            return mService.getConnectionOwnerUid(connectionInfo);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index ce95b60..e7d441d 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.app.PendingIntent;
+import android.net.ConnectionInfo;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -182,4 +183,6 @@
     String getCaptivePortalServerUrl();
 
     byte[] getNetworkWatchlistConfigHash();
+
+    int getConnectionOwnerUid(in ConnectionInfo connectionInfo);
 }
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/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 b9d9007..f947b5e 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -773,6 +773,7 @@
             if (tracingEnabled) {
                 Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
             }
+            ThreadLocalWorkSourceUid.set(Binder.getCallingUid());
             res = onTransact(code, data, reply, flags);
         } catch (RemoteException|RuntimeException e) {
             if (observer != null) {
@@ -793,6 +794,7 @@
             }
             res = true;
         } finally {
+            ThreadLocalWorkSourceUid.clear();
             if (tracingEnabled) {
                 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
             }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 6bd2e76..8681893 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -30,6 +30,8 @@
 
 import dalvik.system.VMRuntime;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -1083,7 +1085,67 @@
         return true;
     }
 
+    /** Build information for a particular device partition. */
+    public static class Partition {
+        /** The name identifying the system partition. */
+        public static final String PARTITION_NAME_SYSTEM = "system";
+
+        private String mName;
+        private String mFingerprint;
+        private long mTimeMs;
+
+        public Partition() {}
+
+        private Partition(String name, String fingerprint, long timeMs) {
+            mName = name;
+            mFingerprint = fingerprint;
+            mTimeMs = timeMs;
+        }
+
+        /** The name of this partition, e.g. "system", or "vendor" */
+        public String getName() {
+            return mName;
+        }
+
+        /** The build fingerprint of this partition, see {@link Build#FINGERPRINT}. */
+        public String getFingerprint() {
+            return mFingerprint;
+        }
+
+        /** The time (ms since epoch), at which this partition was built, see {@link Build#TIME}. */
+        public long getTimeMillis() {
+            return mTimeMs;
+        }
+    }
+
+    /**
+     * Get build information about partitions that have a separate fingerprint defined.
+     *
+     * 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() {
+        ArrayList<Partition> partitions = new ArrayList();
+
+        String[] names = new String[] {
+            "bootimage", "odm", "product", "product_services", Partition.PARTITION_NAME_SYSTEM,
+            "vendor"
+        };
+        for (String name : names) {
+            String fingerprint = SystemProperties.get("ro." + name + ".build.fingerprint");
+            if (TextUtils.isEmpty(fingerprint)) {
+                continue;
+            }
+            long time = getLong("ro." + name + ".build.date.utc") * 1000;
+            partitions.add(new Partition(name, fingerprint, time));
+        }
+
+        return partitions;
+    }
+
     // The following properties only make sense for internal engineering builds.
+
+    /** The time at which the build was produced, given in milliseconds since the UNIX epoch. */
     public static final long TIME = getLong("ro.build.date.utc") * 1000;
     public static final String USER = getString("ro.build.user");
     public static final String HOST = getString("ro.build.host");
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/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index f2e0bdd..5f65620 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -44,6 +44,8 @@
     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 ANGLE_PACKAGE_NAME = "com.android.angle";
+    private static final String GLES_MODE_METADATA_KEY = "com.android.angle.GLES_MODE";
 
     private ClassLoader mClassLoader;
     private String mLayerPath;
@@ -52,8 +54,9 @@
     /**
      * Set up GraphicsEnvironment
      */
-    public void setup(Context context) {
+    public void setup(Context context, Bundle coreSettings) {
         setupGpuLayers(context);
+        setupAngle(context, coreSettings);
         chooseDriver(context);
     }
 
@@ -121,7 +124,6 @@
                     }
                 }
             }
-
         }
 
         // Include the app's lib directory in all cases
@@ -131,6 +133,79 @@
     }
 
     /**
+     * Pass ANGLE details down to trigger enable logic
+     */
+    private static void setupAngle(Context context, Bundle coreSettings) {
+
+        String angleEnabledApp =
+                coreSettings.getString(Settings.Global.ANGLE_ENABLED_APP);
+
+        String packageName = context.getPackageName();
+
+        boolean devOptIn = false;
+        if ((angleEnabledApp != null && packageName != null)
+                && (!angleEnabledApp.isEmpty() && !packageName.isEmpty())
+                && angleEnabledApp.equals(packageName)) {
+
+            if (DEBUG) Log.v(TAG, packageName + " opted in for ANGLE via Developer Setting");
+
+            devOptIn = true;
+        }
+
+        ApplicationInfo appInfo;
+        try {
+            appInfo = context.getPackageManager().getApplicationInfo(packageName,
+                PackageManager.GET_META_DATA);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Failed to get info about current application: " + packageName);
+            return;
+        }
+
+        String appPref = "dontcare";
+        final BaseBundle metadata = appInfo.metaData;
+        if (metadata != null) {
+            final String glesMode = metadata.getString(GLES_MODE_METADATA_KEY);
+            if (glesMode != null) {
+                if (glesMode.equals("angle")) {
+                    appPref = "angle";
+                    if (DEBUG) Log.v(TAG, packageName + " opted for ANGLE via AndroidManifest");
+                } else if (glesMode.equals("native")) {
+                    appPref = "native";
+                    if (DEBUG) Log.v(TAG, packageName + " opted for NATIVE via AndroidManifest");
+                } else {
+                    Log.w(TAG, "Unrecognized GLES_MODE (\"" + glesMode + "\") for " + packageName
+                               + ". Supported values are \"angle\" or \"native\"");
+                }
+            }
+        }
+
+        ApplicationInfo angleInfo;
+        try {
+            angleInfo = context.getPackageManager().getApplicationInfo(ANGLE_PACKAGE_NAME,
+                PackageManager.MATCH_SYSTEM_ONLY);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "ANGLE package '" + ANGLE_PACKAGE_NAME + "' not installed");
+            return;
+        }
+
+        String abi = chooseAbi(angleInfo);
+
+        // Build a path that includes installed native libs and APK
+        StringBuilder sb = new StringBuilder();
+        sb.append(angleInfo.nativeLibraryDir)
+            .append(File.pathSeparator)
+            .append(angleInfo.sourceDir)
+            .append("!/lib/")
+            .append(abi);
+        String paths = sb.toString();
+
+        if (DEBUG) Log.v(TAG, "ANGLE package libs: " + paths);
+
+        // Further opt-in logic is handled in native, so pass relevant info down
+        setAngleInfo(paths, packageName, appPref, devOptIn);
+    }
+
+    /**
      * Choose whether the current process should use the builtin or an updated driver.
      */
     private static void chooseDriver(Context context) {
@@ -218,4 +293,6 @@
     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);
 }
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index e03af9d..f3a9a50 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -739,6 +739,8 @@
 
     private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
         msg.target = this;
+        msg.workSourceUid = ThreadLocalWorkSourceUid.get();
+
         if (mAsynchronous) {
             msg.setAsynchronous(true);
         }
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index ded3a19..5b8abab 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -205,6 +205,7 @@
                 token = observer.messageDispatchStarting();
             }
             try {
+                ThreadLocalWorkSourceUid.set(msg.workSourceUid);
                 msg.target.dispatchMessage(msg);
                 if (observer != null) {
                     observer.messageDispatched(token, msg);
@@ -216,6 +217,7 @@
                 }
                 throw exception;
             } finally {
+                ThreadLocalWorkSourceUid.clear();
                 if (traceTag != 0) {
                     Trace.traceEnd(traceTag);
                 }
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 455d8ed..cd3f301 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.os.MessageProto;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
@@ -74,11 +73,25 @@
     public Messenger replyTo;
 
     /**
+     * Indicates that the uid is not set;
+     *
+     * @hide Only for use within the system server.
+     */
+    public static final int UID_NONE = -1;
+
+    /**
      * Optional field indicating the uid that sent the message.  This is
      * only valid for messages posted by a {@link Messenger}; otherwise,
      * it will be -1.
      */
-    public int sendingUid = -1;
+    public int sendingUid = UID_NONE;
+
+    /**
+     * Optional field indicating the uid that caused this message to be enqueued.
+     *
+     * @hide Only for use within the system server.
+     */
+    public int workSourceUid = UID_NONE;
 
     /** If set message is in use.
      * This flag is set when the message is enqueued and remains set while it
@@ -151,6 +164,7 @@
         m.obj = orig.obj;
         m.replyTo = orig.replyTo;
         m.sendingUid = orig.sendingUid;
+        m.workSourceUid = orig.workSourceUid;
         if (orig.data != null) {
             m.data = new Bundle(orig.data);
         }
@@ -301,7 +315,8 @@
         arg2 = 0;
         obj = null;
         replyTo = null;
-        sendingUid = -1;
+        sendingUid = UID_NONE;
+        workSourceUid = UID_NONE;
         when = 0;
         target = null;
         callback = null;
@@ -329,6 +344,7 @@
         this.obj = o.obj;
         this.replyTo = o.replyTo;
         this.sendingUid = o.sendingUid;
+        this.workSourceUid = o.workSourceUid;
 
         if (o.data != null) {
             this.data = (Bundle) o.data.clone();
@@ -612,6 +628,7 @@
         dest.writeBundle(data);
         Messenger.writeMessengerOrNullToParcel(replyTo, dest);
         dest.writeInt(sendingUid);
+        dest.writeInt(workSourceUid);
     }
 
     private void readFromParcel(Parcel source) {
@@ -625,5 +642,6 @@
         data = source.readBundle();
         replyTo = Messenger.readMessengerOrNullFromParcel(source);
         sendingUid = source.readInt();
+        workSourceUid = source.readInt();
     }
 }
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 89a5def..8ea061e 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1154,10 +1154,15 @@
      *
      * @return True if the set was allowed.
      *
-     * @see #isPowerSaveMode()
-     *
      * @hide
+     * @see #isPowerSaveMode()
      */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.DEVICE_POWER,
+            android.Manifest.permission.POWER_SAVER
+    })
     public boolean setPowerSaveMode(boolean mode) {
         try {
             return mService.setPowerSaveMode(mode);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 5cd2ffc..0f64c45 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -42,6 +42,11 @@
     public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary";
 
     /**
+     * An invalid UID value.
+     */
+    public static final int INVALID_UID = -1;
+
+    /**
      * Defines the root UID.
      * @hide
      */
@@ -478,6 +483,8 @@
      * @param appDataDir null-ok the data directory of the app.
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
+     * @param packagesForUid null-ok all the packages with the same uid as this process.
+     * @param visibleVols null-ok storage volumes that can be accessed by this process.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * 
      * @return An object that describes the result of the attempt to start the process.
@@ -496,10 +503,13 @@
                                   @Nullable String appDataDir,
                                   @Nullable String invokeWith,
                                   @Nullable String packageName,
+                                  @Nullable String[] packagesForUid,
+                                  @Nullable String[] visibleVols,
                                   @Nullable String[] zygoteArgs) {
         return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
-                    abi, instructionSet, appDataDir, invokeWith, packageName, zygoteArgs);
+                    abi, instructionSet, appDataDir, invokeWith, packageName,
+                    packagesForUid, visibleVols, zygoteArgs);
     }
 
     /** @hide */
@@ -514,10 +524,13 @@
                                   @Nullable String appDataDir,
                                   @Nullable String invokeWith,
                                   @Nullable String packageName,
+                                  @Nullable String[] packagesForUid,
+                                  @Nullable String[] visibleVols,
                                   @Nullable String[] zygoteArgs) {
         return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
-                    abi, instructionSet, appDataDir, invokeWith, packageName, zygoteArgs);
+                    abi, instructionSet, appDataDir, invokeWith, packageName,
+                    packagesForUid, visibleVols, zygoteArgs);
     }
 
     /**
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 3e8e885..8492b0c 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -36,16 +36,12 @@
 import android.view.Display;
 import android.view.WindowManager;
 
-import com.android.internal.logging.MetricsLogger;
-
 import libcore.io.Streams;
 
-import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
@@ -97,7 +93,7 @@
     /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static final File RECOVERY_DIR = new File("/cache/recovery");
     private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
-    private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install");
+    private static final String LAST_INSTALL_PATH = "last_install";
     private static final String LAST_PREFIX = "last_";
     private static final String ACTION_EUICC_FACTORY_RESET =
             "com.android.internal.action.EUICC_FACTORY_RESET";
@@ -935,116 +931,6 @@
         throw new IOException("Reboot failed (no permissions?)");
     }
 
-    // Read last_install; then report time (in seconds) and I/O (in MiB) for
-    // this update to tron.
-    // Only report on the reboots immediately after an OTA update.
-    private static void parseLastInstallLog(Context context) {
-        try (BufferedReader in = new BufferedReader(new FileReader(LAST_INSTALL_FILE))) {
-            String line = null;
-            int bytesWrittenInMiB = -1, bytesStashedInMiB = -1;
-            int timeTotal = -1;
-            int uncryptTime = -1;
-            int sourceVersion = -1;
-            int temperatureStart = -1;
-            int temperatureEnd = -1;
-            int temperatureMax = -1;
-            int errorCode = -1;
-            int causeCode = -1;
-
-            while ((line = in.readLine()) != null) {
-                // Here is an example of lines in last_install:
-                // ...
-                // time_total: 101
-                // bytes_written_vendor: 51074
-                // bytes_stashed_vendor: 200
-                int numIndex = line.indexOf(':');
-                if (numIndex == -1 || numIndex + 1 >= line.length()) {
-                    continue;
-                }
-                String numString = line.substring(numIndex + 1).trim();
-                long parsedNum;
-                try {
-                    parsedNum = Long.parseLong(numString);
-                } catch (NumberFormatException ignored) {
-                    Log.e(TAG, "Failed to parse numbers in " + line);
-                    continue;
-                }
-
-                final int MiB = 1024 * 1024;
-                int scaled;
-                try {
-                    if (line.startsWith("bytes")) {
-                        scaled = Math.toIntExact(parsedNum / MiB);
-                    } else {
-                        scaled = Math.toIntExact(parsedNum);
-                    }
-                } catch (ArithmeticException ignored) {
-                    Log.e(TAG, "Number overflows in " + line);
-                    continue;
-                }
-
-                if (line.startsWith("time")) {
-                    timeTotal = scaled;
-                } else if (line.startsWith("uncrypt_time")) {
-                    uncryptTime = scaled;
-                } else if (line.startsWith("source_build")) {
-                    sourceVersion = scaled;
-                } else if (line.startsWith("bytes_written")) {
-                    bytesWrittenInMiB = (bytesWrittenInMiB == -1) ? scaled :
-                            bytesWrittenInMiB + scaled;
-                } else if (line.startsWith("bytes_stashed")) {
-                    bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled :
-                            bytesStashedInMiB + scaled;
-                } else if (line.startsWith("temperature_start")) {
-                    temperatureStart = scaled;
-                } else if (line.startsWith("temperature_end")) {
-                    temperatureEnd = scaled;
-                } else if (line.startsWith("temperature_max")) {
-                    temperatureMax = scaled;
-                } else if (line.startsWith("error")) {
-                    errorCode = scaled;
-                } else if (line.startsWith("cause")) {
-                    causeCode = scaled;
-                }
-            }
-
-            // Don't report data to tron if corresponding entry isn't found in last_install.
-            if (timeTotal != -1) {
-                MetricsLogger.histogram(context, "ota_time_total", timeTotal);
-            }
-            if (uncryptTime != -1) {
-                MetricsLogger.histogram(context, "ota_uncrypt_time", uncryptTime);
-            }
-            if (sourceVersion != -1) {
-                MetricsLogger.histogram(context, "ota_source_version", sourceVersion);
-            }
-            if (bytesWrittenInMiB != -1) {
-                MetricsLogger.histogram(context, "ota_written_in_MiBs", bytesWrittenInMiB);
-            }
-            if (bytesStashedInMiB != -1) {
-                MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB);
-            }
-            if (temperatureStart != -1) {
-                MetricsLogger.histogram(context, "ota_temperature_start", temperatureStart);
-            }
-            if (temperatureEnd != -1) {
-                MetricsLogger.histogram(context, "ota_temperature_end", temperatureEnd);
-            }
-            if (temperatureMax != -1) {
-                MetricsLogger.histogram(context, "ota_temperature_max", temperatureMax);
-            }
-            if (errorCode != -1) {
-                MetricsLogger.histogram(context, "ota_non_ab_error_code", errorCode);
-            }
-            if (causeCode != -1) {
-                MetricsLogger.histogram(context, "ota_non_ab_cause_code", causeCode);
-            }
-
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to read lines in last_install", e);
-        }
-    }
-
     /**
      * Called after booting to process and remove recovery-related files.
      * @return the log file from recovery, or null if none was found.
@@ -1062,9 +948,6 @@
             Log.e(TAG, "Error reading recovery log", e);
         }
 
-        if (log != null) {
-            parseLastInstallLog(context);
-        }
 
         // Only remove the OTA package if it's partially processed (uncrypt'd).
         boolean reservePackage = BLOCK_MAP_FILE.exists();
@@ -1095,7 +978,8 @@
         // GmsCore to avoid re-downloading everything again.
         String[] names = RECOVERY_DIR.list();
         for (int i = 0; names != null && i < names.length; i++) {
-            if (names[i].startsWith(LAST_PREFIX)) continue;
+            // Do not remove the last_install file since the recovery-persist takes care of it.
+            if (names[i].startsWith(LAST_PREFIX) || names[i].equals(LAST_INSTALL_PATH)) continue;
             if (reservePackage && names[i].equals(BLOCK_MAP_FILE.getName())) continue;
             if (reservePackage && names[i].equals(UNCRYPT_PACKAGE_FILE.getName())) continue;
 
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index b13bcac..72e1ab9 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -15,8 +15,10 @@
  */
 package android.os;
 
-import java.io.ByteArrayOutputStream;
-import java.nio.charset.StandardCharsets;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Wrapper class for sending data from Android OS to StatsD.
@@ -24,39 +26,28 @@
  * @hide
  */
 public final class StatsLogEventWrapper implements Parcelable {
-    private ByteArrayOutputStream mStorage = new ByteArrayOutputStream();
+    static final boolean DEBUG = false;
+    static final String TAG = "StatsLogEventWrapper";
 
-    // Below are constants copied from log/log.h
-    private static final int EVENT_TYPE_INT = 0;  /* int32_t */
-    private static final int EVENT_TYPE_LONG = 1; /* int64_t */
-    private static final int EVENT_TYPE_STRING = 2;
-    private static final int EVENT_TYPE_LIST = 3;
-    private static final int EVENT_TYPE_FLOAT = 4;
+    // Keep in sync with FieldValue.h enums
+    private static final int EVENT_TYPE_UNKNOWN = 0;
+    private static final int EVENT_TYPE_INT = 1; /* int32_t */
+    private static final int EVENT_TYPE_LONG = 2; /* int64_t */
+    private static final int EVENT_TYPE_FLOAT = 3;
+    private static final int EVENT_TYPE_DOUBLE = 4;
+    private static final int EVENT_TYPE_STRING = 5;
+    private static final int EVENT_TYPE_STORAGE = 6;
 
-    // Keep this in sync with system/core/logcat/event.logtags
-    private static final int STATS_BUFFER_TAG_ID = 1937006964;
-    /**
-     * Creates a log_event that is binary-encoded as implemented in
-     * system/core/liblog/log_event_list.c; this allows us to use the same parsing logic in statsd
-     * for pushed and pulled data. The write* methods must be called in the same order as their
-     * field number. There is no checking that the correct number of write* methods is called.
-     * We also write an END_LIST character before beginning to write to parcel, but this END_LIST
-     * may be unnecessary.
-     *
-     * @param tag    The integer representing the tag for this event.
-     * @param fields The number of fields specified in this event.
-     */
-    public StatsLogEventWrapper(long elapsedNanos, int tag, int fields) {
-        // Write four bytes from tag, starting with least-significant bit.
-        // For pulled data, this tag number is not really used. We use the same tag number as
-        // pushed ones to be consistent.
-        write4Bytes(STATS_BUFFER_TAG_ID);
-        mStorage.write(EVENT_TYPE_LIST); // This is required to start the log entry.
-        mStorage.write(fields + 2); // Indicate number of elements in this list. +1 for the tag
-        // The first element is the elapsed realtime.
-        writeLong(elapsedNanos);
-        // The second element is the real atom tag number
-        writeInt(tag);
+    List<Integer> mTypes = new ArrayList<>();
+    List<Object> mValues = new ArrayList<>();
+    int mTag;
+    long mElapsedTimeNs;
+    long mWallClockTimeNs;
+
+    public StatsLogEventWrapper(int tag, long elapsedTimeNs, long wallClockTimeNs) {
+        this.mTag = tag;
+        this.mElapsedTimeNs = elapsedTimeNs;
+        this.mWallClockTimeNs = wallClockTimeNs;
     }
 
     /**
@@ -79,69 +70,103 @@
                 }
             };
 
-    private void write4Bytes(int val) {
-        mStorage.write(val);
-        mStorage.write(val >>> 8);
-        mStorage.write(val >>> 16);
-        mStorage.write(val >>> 24);
-    }
-
-    private void write8Bytes(long val) {
-        write4Bytes((int) (val & 0xFFFFFFFF)); // keep the lowe 32-bits
-        write4Bytes((int) (val >>> 32)); // Write the high 32-bits.
-    }
-
     /**
-     * Adds 32-bit integer to output.
+     * Write a int value.
      */
     public void writeInt(int val) {
-        mStorage.write(EVENT_TYPE_INT);
-        write4Bytes(val);
+        mTypes.add(EVENT_TYPE_INT);
+        mValues.add(val);
     }
 
     /**
-     * Adds 64-bit long to output.
+     * Write a long value.
      */
     public void writeLong(long val) {
-        mStorage.write(EVENT_TYPE_LONG);
-        write8Bytes(val);
+        mTypes.add(EVENT_TYPE_LONG);
+        mValues.add(val);
     }
 
     /**
-     * Adds a 4-byte floating point value to output.
-     */
-    public void writeFloat(float val) {
-        int v = Float.floatToIntBits(val);
-        mStorage.write(EVENT_TYPE_FLOAT);
-        write4Bytes(v);
-    }
-
-    /**
-     * Adds a string to the output.
+     * Write a string value.
      */
     public void writeString(String val) {
-        mStorage.write(EVENT_TYPE_STRING);
-        write4Bytes(val.length());
-        byte[] bytes = val.getBytes(StandardCharsets.UTF_8);
-        mStorage.write(bytes, 0, bytes.length);
+        mTypes.add(EVENT_TYPE_STRING);
+        // use empty string for null
+        mValues.add(val == null ? "" : val);
     }
 
     /**
-     * Adds a boolean by adding either a 1 or 0 to the output.
+     * 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) {
+        mTypes.add(EVENT_TYPE_STORAGE);
+        mValues.add(val);
+    }
+
+    /**
+     * Write a boolean value.
      */
     public void writeBoolean(boolean val) {
-        int toWrite = val ? 1 : 0;
-        mStorage.write(EVENT_TYPE_INT);
-        write4Bytes(toWrite);
+        mTypes.add(EVENT_TYPE_INT);
+        mValues.add(val ? 1 : 0);
     }
 
     /**
      * Writes the stored fields to a byte array. Will first write a new-line character to denote
      * END_LIST before writing contents to byte array.
      */
+
     public void writeToParcel(Parcel out, int flags) {
-        mStorage.write(10); // new-line character is same as END_LIST
-        out.writeByteArray(mStorage.toByteArray());
+        if (DEBUG) {
+            Slog.d(TAG,
+                    "Writing " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs + " and "
+                            + mTypes.size() + " elements.");
+        }
+        out.writeInt(mTag);
+        out.writeLong(mElapsedTimeNs);
+        out.writeLong(mWallClockTimeNs);
+        out.writeInt(mTypes.size());
+        for (int i = 0; i < mTypes.size(); i++) {
+            out.writeInt(mTypes.get(i));
+            switch (mTypes.get(i)) {
+                case EVENT_TYPE_INT:
+                    out.writeInt((int) mValues.get(i));
+                    break;
+                case EVENT_TYPE_LONG:
+                    out.writeLong((long) mValues.get(i));
+                    break;
+                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;
+                case EVENT_TYPE_STORAGE:
+                    out.writeByteArray((byte[]) mValues.get(i));
+                    break;
+                default:
+                    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/ThreadLocalWorkSourceUid.java b/core/java/android/os/ThreadLocalWorkSourceUid.java
new file mode 100644
index 0000000..df1d275
--- /dev/null
+++ b/core/java/android/os/ThreadLocalWorkSourceUid.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+ * @hide Only for use within system server.
+ */
+public final class ThreadLocalWorkSourceUid {
+    public static final int UID_NONE = Message.UID_NONE;
+    private static final ThreadLocal<Integer> sWorkSourceUid =
+            ThreadLocal.withInitial(() -> UID_NONE);
+
+    /** Returns the original work source uid. */
+    public static int get() {
+        return sWorkSourceUid.get();
+    }
+
+    /** Sets the original work source uid. */
+    public static void set(int uid) {
+        sWorkSourceUid.set(uid);
+    }
+
+    /** Clears the stored work source uid. */
+    public static void clear() {
+        sWorkSourceUid.set(UID_NONE);
+    }
+
+    private ThreadLocalWorkSourceUid() {
+    }
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index b0891050..1282170 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -256,6 +256,7 @@
     /**
      * Specifies if a user is disallowed from enabling the
      * "Unknown Sources" setting, that allows installation of apps from unknown sources.
+     * Unknown sources exclude adb and special apps such as trusted app stores.
      * The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -267,6 +268,22 @@
     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}.
+     *
+     * Specifies if all users on the device are disallowed from enabling the
+     * "Unknown Sources" setting, that allows installation of apps from unknown sources.
+     * The default value is <code>false</code>.
+     *
+     * <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_INSTALL_UNKNOWN_SOURCES_GLOBALLY =
+            "no_install_unknown_sources_globally";
+
+    /**
      * Specifies if a user is disallowed from configuring bluetooth.
      * This does <em>not</em> restrict the user from turning bluetooth on or off.
      * The default value is <code>false</code>.
@@ -1669,8 +1686,9 @@
      /**
      * @hide
      * Returns whether the given user has been disallowed from performing certain actions
-     * or setting certain settings through UserManager. This method disregards restrictions
-     * set by device policy.
+     * or setting certain settings through UserManager (e.g. this type of restriction would prevent
+     * the guest user from doing certain things, such as making calls). This method disregards
+     * restrictions set by device policy.
      * @param restrictionKey the string key representing the restriction
      * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
      */
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 99181ac..7fd0a4b 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -215,6 +215,8 @@
      * @param appDataDir null-ok the data directory of the app.
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
+     * @param packagesForUid null-ok all the packages with the same uid as this process.
+     * @param visibleVols null-ok storage volumes that can be accessed by this process.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      *
      * @return An object that describes the result of the attempt to start the process.
@@ -231,12 +233,14 @@
                                                   @Nullable String appDataDir,
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
+                                                  @Nullable String[] packagesForUid,
+                                                  @Nullable String[] visibleVols,
                                                   @Nullable String[] zygoteArgs) {
         try {
             return startViaZygote(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
-                    packageName, zygoteArgs);
+                    packageName, packagesForUid, visibleVols, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
                     "Starting VM process through Zygote failed");
@@ -355,6 +359,8 @@
      * @param startChildZygote Start a sub-zygote. This creates a new zygote process
      * that has its state cloned from this zygote process.
      * @param packageName null-ok the name of the package this process belongs to.
+     * @param packagesForUid null-ok all the packages with the same uid as this process.
+     * @param visibleVols null-ok storage volumes that can be accessed by this process.
      * @param extraArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
      * @throws ZygoteStartFailedEx if process start failed for any reason
@@ -372,6 +378,8 @@
                                                       @Nullable String invokeWith,
                                                       boolean startChildZygote,
                                                       @Nullable String packageName,
+                                                      @Nullable String[] packagesForUid,
+                                                      @Nullable String[] visibleVols,
                                                       @Nullable String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
         ArrayList<String> argsForZygote = new ArrayList<String>();
@@ -439,6 +447,32 @@
             argsForZygote.add("--package-name=" + packageName);
         }
 
+        if (packagesForUid != null && packagesForUid.length > 0) {
+            final StringBuilder sb = new StringBuilder();
+            sb.append("--packages-for-uid=");
+
+            for (int i = 0; i < packagesForUid.length; ++i) {
+                if (i != 0) {
+                    sb.append(',');
+                }
+                sb.append(packagesForUid[i]);
+            }
+            argsForZygote.add(sb.toString());
+        }
+
+        if (visibleVols != null && visibleVols.length > 0) {
+            final StringBuilder sb = new StringBuilder();
+            sb.append("--visible-vols=");
+
+            for (int i = 0; i < visibleVols.length; ++i) {
+                if (i != 0) {
+                    sb.append(',');
+                }
+                sb.append(visibleVols[i]);
+            }
+            argsForZygote.add(sb.toString());
+        }
+
         argsForZygote.add(processClass);
 
         if (extraArgs != null) {
@@ -746,7 +780,8 @@
             result = startViaZygote(processClass, niceName, uid, gid,
                     gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
                     abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
-                    true /* startChildZygote */, null /* packageName */, extraArgs);
+                    true /* startChildZygote */, null /* packageName */,
+                    null /* packagesForUid */, null /* visibleVolumes */, extraArgs);
         } catch (ZygoteStartFailedEx ex) {
             throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
         }
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index d850e27..1f54ea5 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -89,8 +89,13 @@
      * @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
+     * @param userId The userId in which the storage needs to be mounted.
      */
     public abstract void mountExternalStorageForApp(String packageName, int appId,
             String sharedUserId, int userId);
+
+    /**
+     * @return Labels of storage volumes that are visible to the given userId.
+     */
+    public abstract String[] getVisibleVolumesForUser(int userId);
 }
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index afd38369..e55afb6 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -157,7 +157,7 @@
     public final DiskInfo disk;
     public final String partGuid;
     public int mountFlags = 0;
-    public int mountUserId = -1;
+    public int mountUserId = UserHandle.USER_NULL;
     @UnsupportedAppUsage
     public int state = STATE_UNMOUNTED;
     public String fsType;
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
new file mode 100644
index 0000000..aa44eb7
--- /dev/null
+++ b/core/java/android/permission/PermissionManager.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.permission;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+
+import com.android.internal.annotations.Immutable;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * System level service for accessing the permission capabilities of the platform.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.PERMISSION_SERVICE)
+public final class PermissionManager {
+    /**
+     * {@link android.content.pm.PackageParser} needs access without having a {@link Context}.
+     *
+     * @hide
+     */
+    public static final SplitPermissionInfo[] SPLIT_PERMISSIONS = new SplitPermissionInfo[]{
+            // 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},
+                    android.os.Build.VERSION_CODES.CUR_DEVELOPMENT + 1),
+            new SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
+                    new String[]{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},
+                    android.os.Build.VERSION_CODES.JELLY_BEAN),
+            new SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION,
+                    new String[]{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)};
+
+    private final @NonNull Context mContext;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param context The current context in which to operate.
+     * @hide
+     */
+    public PermissionManager(@NonNull Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Get list 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
+     * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#P0}
+     * 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 Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside
+     * {@{@link SplitPermissionInfo#getNewPermissions}) is added.
+     *
+     * <p>Note: Regular apps do not have to worry about this. The platform and permission controller
+     * automatically add the new permissions where needed.
+     *
+     * @return All permissions that are split.
+     */
+    public @NonNull List<SplitPermissionInfo> getSplitPermissions() {
+        return Arrays.asList(SPLIT_PERMISSIONS);
+    }
+
+    /**
+     * A permission that was added in a previous API level might have split into several
+     * permissions. This object describes one such split.
+     */
+    @Immutable
+    public static final class SplitPermissionInfo {
+        private final @NonNull String mRootPerm;
+        private final @NonNull String[] mNewPerms;
+        private final int mTargetSdk;
+
+        /**
+         * Get the permission that is split.
+         */
+        public @NonNull String getRootPermission() {
+            return mRootPerm;
+        }
+
+        /**
+         * Get the permissions that are added.
+         */
+        public @NonNull String[] getNewPermissions() {
+            return mNewPerms;
+        }
+
+        /**
+         * Get the target API level when the permission was split.
+         */
+        public int getTargetSdk() {
+            return mTargetSdk;
+        }
+
+        private SplitPermissionInfo(@NonNull String rootPerm, @NonNull String[] newPerms,
+                int targetSdk) {
+            mRootPerm = rootPerm;
+            mNewPerms = newPerms;
+            mTargetSdk = targetSdk;
+        }
+    }
+}
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index f2da21e..18aea03 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -16,6 +16,7 @@
 
 package android.permissionpresenterservice;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Context;
@@ -73,12 +74,13 @@
     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
 
     /**
-     * Revoke the permission {@code permissionName} for app {@code packageName}
+     * Revokes the permission {@code permissionName} for app {@code packageName}
      *
      * @param packageName The package for which to revoke
      * @param permissionName The permission to revoke
      */
-    public abstract void onRevokeRuntimePermission(String packageName, String permissionName);
+    public abstract void onRevokeRuntimePermission(@NonNull String packageName,
+            @NonNull String permissionName);
 
     @Override
     public final IBinder onBind(Intent intent) {
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 ee64ca2..8c40e0e 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -942,13 +942,26 @@
         return false;
     }
 
-    /** {@hide} */
+    /**
+     * Test if the given URI represents roots backed by {@link DocumentsProvider}.
+     *
+     * @see #buildRootsUri(String)
+     *
+     * {@hide}
+     */
+    public static boolean isRootsUri(Context context, @Nullable Uri uri) {
+        return isRootUri(context, uri, 1 /* pathSize */);
+    }
+
+    /**
+     * Test if the given URI represents specific root backed by {@link DocumentsProvider}.
+     *
+     * @see #buildRootUri(String, String)
+     *
+     * {@hide}
+     */
     public static boolean isRootUri(Context context, @Nullable Uri uri) {
-        if (isContentUri(uri) && isDocumentsProvider(context, uri.getAuthority())) {
-            final List<String> paths = uri.getPathSegments();
-            return (paths.size() == 2 && PATH_ROOT.equals(paths.get(0)));
-        }
-        return false;
+        return isRootUri(context, uri, 2 /* pathSize */);
     }
 
     /** {@hide} */
@@ -967,6 +980,14 @@
         return (paths.size() >= 2 && PATH_TREE.equals(paths.get(0)));
     }
 
+    private static boolean isRootUri(Context context, @Nullable Uri uri, int pathSize) {
+        if (isContentUri(uri) && isDocumentsProvider(context, uri.getAuthority())) {
+            final List<String> paths = uri.getPathSegments();
+            return (paths.size() == pathSize && PATH_ROOT.equals(paths.get(0)));
+        }
+        return false;
+    }
+
     private static boolean isDocumentsProvider(Context context, String authority) {
         final Intent intent = new Intent(PROVIDER_INTERFACE);
         final List<ResolveInfo> infos = context.getPackageManager()
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 82459b1..828fd73 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -1318,18 +1318,6 @@
         }
 
         public static final class Media implements AudioColumns {
-
-            private static final String[] EXTERNAL_PATHS;
-
-            static {
-                String secondary_storage = System.getenv("SECONDARY_STORAGE");
-                if (secondary_storage != null) {
-                    EXTERNAL_PATHS = secondary_storage.split(":");
-                } else {
-                    EXTERNAL_PATHS = new String[0];
-                }
-            }
-
             /**
              * Get the content:// style URI for the audio media table on the
              * given volume.
@@ -1343,14 +1331,9 @@
             }
 
             public static Uri getContentUriForPath(String path) {
-                for (String ep : EXTERNAL_PATHS) {
-                    if (path.startsWith(ep)) {
-                        return EXTERNAL_CONTENT_URI;
-                    }
-                }
-
-                return (path.startsWith(Environment.getExternalStorageDirectory().getPath()) ?
-                        EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI);
+                return (path.startsWith(
+                        Environment.getStorageDirectory().getAbsolutePath() + "/")
+                        ? EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI);
             }
 
             /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index aa178fb..acb7577 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
@@ -7267,12 +7277,12 @@
         private static final Validator DOZE_DOUBLE_TAP_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
-         * Whether the device should pulse on reach gesture.
+         * Gesture that wakes up the lock screen.
          * @hide
          */
-        public static final String DOZE_REACH_GESTURE = "doze_reach_gesture";
+        public static final String DOZE_WAKE_LOCK_SCREEN_GESTURE = "doze_wake_lock_screen_gesture";
 
-        private static final Validator DOZE_REACH_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
+        private static final Validator DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
          * Gesture that wakes up the display, showing the ambient version of the status bar.
@@ -7365,6 +7375,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
@@ -7689,6 +7708,15 @@
                 BOOLEAN_VALIDATOR;
 
         /**
+         * Whether or not face unlock is allowed for apps (through BiometricPrompt).
+         * @hide
+         */
+        public static final String FACE_UNLOCK_APP_ENABLED = "face_unlock_app_enabled";
+
+        private static final Validator FACE_UNLOCK_APP_ENABLED_VALIDATOR =
+                BOOLEAN_VALIDATOR;
+
+        /**
          * Whether the assist gesture should be enabled.
          *
          * @hide
@@ -8184,11 +8212,12 @@
             DOZE_ALWAYS_ON,
             DOZE_PICK_UP_GESTURE,
             DOZE_DOUBLE_TAP_GESTURE,
-            DOZE_REACH_GESTURE,
+            DOZE_WAKE_LOCK_SCREEN_GESTURE,
             DOZE_WAKE_SCREEN_GESTURE,
             NFC_PAYMENT_DEFAULT_COMPONENT,
             AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
             FACE_UNLOCK_KEYGUARD_ENABLED,
+            FACE_UNLOCK_APP_ENABLED,
             ASSIST_GESTURE_ENABLED,
             ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
             ASSIST_GESTURE_WAKE_ENABLED,
@@ -8331,12 +8360,13 @@
             VALIDATORS.put(DOZE_ALWAYS_ON, DOZE_ALWAYS_ON_VALIDATOR);
             VALIDATORS.put(DOZE_PICK_UP_GESTURE, DOZE_PICK_UP_GESTURE_VALIDATOR);
             VALIDATORS.put(DOZE_DOUBLE_TAP_GESTURE, DOZE_DOUBLE_TAP_GESTURE_VALIDATOR);
-            VALIDATORS.put(DOZE_REACH_GESTURE, DOZE_REACH_GESTURE_VALIDATOR);
+            VALIDATORS.put(DOZE_WAKE_LOCK_SCREEN_GESTURE, DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR);
             VALIDATORS.put(DOZE_WAKE_SCREEN_GESTURE, DOZE_WAKE_SCREEN_GESTURE_VALIDATOR);
             VALIDATORS.put(NFC_PAYMENT_DEFAULT_COMPONENT, NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR);
             VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
                     AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
             VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
+            VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
             VALIDATORS.put(ASSIST_GESTURE_ENABLED, ASSIST_GESTURE_ENABLED_VALIDATOR);
             VALIDATORS.put(ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
                     ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR);
@@ -9242,6 +9272,19 @@
        public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
 
         /**
+         * Whether the wifi data connection should remain active even when higher
+         * priority networks like Ethernet are active, to keep both networks.
+         * In the case where higher priority networks are connected, wifi will be
+         * unused unless an application explicitly requests to use it.
+         *
+         * See ConnectivityService for more info.
+         *
+         * (0 = disabled, 1 = enabled)
+         * @hide
+         */
+        public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested";
+
+        /**
          * Size of the event buffer for IP connectivity metrics.
          * @hide
          */
@@ -9593,8 +9636,7 @@
          * Use the old dnsmasq DHCP server for tethering instead of the framework implementation.
          *
          * Integer values are interpreted as boolean, and the absence of an explicit setting
-         * is interpreted as |true|.
-         * TODO: make the default |false|
+         * is interpreted as |false|.
          * @hide
          */
         public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
@@ -10811,6 +10853,12 @@
                 = "activity_starts_logging_enabled";
 
         /**
+         * @hide
+         * @see com.android.server.appbinding.AppBindingConstants
+         */
+        public static final String APP_BINDING_CONSTANTS = "app_binding_constants";
+
+        /**
          * App ops specific settings.
          * This is encoded as a key=value list, separated by commas. Ex:
          *
@@ -11570,6 +11618,12 @@
         public static final String GPU_DEBUG_APP = "gpu_debug_app";
 
         /**
+         * App should try to use ANGLE
+         * @hide
+         */
+        public static final String ANGLE_ENABLED_APP = "angle_enabled_app";
+
+        /**
          * Ordered GPU debug layer list
          * i.e. <layer1>:<layer2>:...:<layerN>
          * @hide
@@ -12297,6 +12351,18 @@
                 "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, SettingsProvider's restoreAnyVersion="true" attribute will be ignored
          * and restoring to lower version of platform API will be skipped.
          *
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index 119f5d0..4f4d62a 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -16,26 +16,23 @@
 
 package android.security.net.config;
 
-import android.os.Environment;
-import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.Pair;
+
+import libcore.io.IoUtils;
+
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.InputStream;
 import java.io.IOException;
-import java.security.cert.Certificate;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Collections;
 import java.util.Set;
-import libcore.io.IoUtils;
-
-import com.android.org.conscrypt.Hex;
-import com.android.org.conscrypt.NativeCrypto;
 
 import javax.security.auth.x500.X500Principal;
 
@@ -192,8 +189,36 @@
     }
 
     private String getHash(X500Principal name) {
-        int hash = NativeCrypto.X509_NAME_hash_old(name);
-        return Hex.intToHexString(hash, 8);
+        int hash = hashName(name);
+        return intToHexString(hash, 8);
+    }
+
+    private static final char[] DIGITS = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+    private static String intToHexString(int i, int minWidth) {
+        int bufLen = 8;  // Max number of hex digits in an int
+        char[] buf = new char[bufLen];
+        int cursor = bufLen;
+
+        do {
+            buf[--cursor] = DIGITS[i & 0xf];
+        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
+
+        return new String(buf, cursor, bufLen - cursor);
+    }
+
+    // This code matches the code in X509_NAME_hash_old() in Conscrypt, which in turn matches
+    // the names of certificate files.  It must be kept in sync.
+    private static int hashName(X500Principal principal) {
+        try {
+            byte[] digest = MessageDigest.getInstance("MD5").digest(principal.getEncoded());
+            int offset = 0;
+            return (((digest[offset++] & 0xff) << 0) | ((digest[offset++] & 0xff) << 8)
+                    | ((digest[offset++] & 0xff) << 16) | ((digest[offset] & 0xff) << 24));
+        } catch (NoSuchAlgorithmException e) {
+            throw new AssertionError(e);
+        }
     }
 
     private X509Certificate readCertificate(String file) {
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 6c18b45..573d577 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -651,14 +651,11 @@
     /**
      * Called when the user requests the service to save the contents of a screen.
      *
-     * <p>Service must call one of the {@link SaveCallback} methods (like
-     * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
-     * to notify the Android System of the result of the request.
-     *
      * <p>If the service could not handle the request right away&mdash;for example, because it must
      * launch an activity asking the user to authenticate first or because the network is
      * down&mdash;the service could keep the {@link SaveRequest request} and reuse it later,
-     * but the service must call {@link SaveCallback#onSuccess()} right away.
+     * but the service <b>must always</b> call {@link SaveCallback#onSuccess()} or
+     * {@link SaveCallback#onSuccess(android.content.IntentSender)} right away.
      *
      * <p><b>Note:</b> To retrieve the actual value of fields input by the user, the service
      * should call
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 1695c13..06e2896 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.os.RemoteException;
+import android.util.Log;
 
 /**
  * <p><code>FillCallback</code> handles autofill requests from the {@link AutofillService} into
@@ -28,6 +29,9 @@
  * <a href="/guide/topics/text/autofill-services">Build autofill services</a>.
  */
 public final class FillCallback {
+
+    private static final String TAG = "FillCallback";
+
     private final IFillCallback mCallback;
     private final int mRequestId;
     private boolean mCalled;
@@ -39,13 +43,20 @@
     }
 
     /**
-     * Notifies the Android System that an
-     * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
-     * FillCallback)} was successfully fulfilled by the service.
+     * Notifies the Android System that a fill request
+     * ({@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
+     * FillCallback)}) was successfully fulfilled by the service.
      *
-     * @param response autofill information for that activity, or {@code null} when the activity
-     * cannot be autofilled (for example, if it only contains read-only fields). See
-     * {@link FillResponse} for examples.
+     * <p>This method should always be called, even if the service doesn't have the heuristics to
+     * fulfill the request (in which case it should be called with {@code null}).
+     *
+     * <p>See the main {@link AutofillService} documentation for more details and examples.
+     *
+     * @param response autofill information for that activity, or {@code null} when the service
+     * cannot autofill the activity.
+     *
+     * @throws IllegalStateException if this method or {@link #onFailure(CharSequence)} was already
+     * called.
      */
     public void onSuccess(@Nullable FillResponse response) {
         assertNotCalled();
@@ -63,13 +74,33 @@
     }
 
     /**
-     * Notifies the Android System that an
+     * Notifies the Android System that a fill request (
      * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
-     * FillCallback)} could not be fulfilled by the service.
+     * FillCallback)}) could not be fulfilled by the service (for example, because the user data was
+     * not available yet), so the request could be retried later.
      *
-     * @param message error message to be displayed to the user.
+     * <p><b>Note: </b>this method should not be used when the service didn't have the heursitics to
+     * fulfill the request; in this case, the service should call {@link #onSuccess(FillResponse)
+     * onSuccess(null)} instead.
+     *
+     * <p><b>Note: </b>prior to {@link android.os.Build.VERSION_CODES#Q}, this
+     * method was not working as intended and the service should always call
+     * {@link #onSuccess(FillResponse) onSuccess(null)} instead.
+     *
+     * <p><b>Note: </b>for apps targeting {@link android.os.Build.VERSION_CODES#Q} or higher, this
+     * method just logs the message on {@code logcat}; for apps targetting older SDKs, it also
+     * displays the message to user using a {@link android.widget.Toast}. Generally speaking, you
+     * should not display an error to the user if the request failed, unless the request had the
+     * {@link FillRequest#FLAG_MANUAL_REQUEST} flag.
+     *
+     * @param message error message. <b>Note: </b> this message should <b>not</b> contain PII
+     * (Personally Identifiable Information, such as username or email address).
+     *
+     * @throws IllegalStateException if this method or {@link #onSuccess(FillResponse)} was already
+     * called.
      */
     public void onFailure(@Nullable CharSequence message) {
+        Log.w(TAG, "onFailure(): " + message);
         assertNotCalled();
         mCalled = true;
         try {
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index 855981a..1753ecf 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -21,6 +21,7 @@
 import android.app.Activity;
 import android.content.IntentSender;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.android.internal.util.Preconditions;
 
@@ -29,6 +30,9 @@
  * autofilled.
  */
 public final class SaveCallback {
+
+    private static final String TAG = "SaveCallback";
+
     private final ISaveCallback mCallback;
     private boolean mCalled;
 
@@ -41,6 +45,9 @@
      * Notifies the Android System that an
      * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} was successfully handled
      * by the service.
+     *
+     * @throws IllegalStateException if this method, {@link #onSuccess(IntentSender)}, or
+     * {@link #onFailure(CharSequence)} was already called.
      */
     public void onSuccess() {
         onSuccessInternal(null);
@@ -58,6 +65,9 @@
      *
      * @param intentSender intent that will be launched from the context of activity being
      * autofilled.
+     *
+     * @throws IllegalStateException if this method, {@link #onSuccess()},
+     * or {@link #onFailure(CharSequence)} was already called.
      */
     public void onSuccess(@NonNull IntentSender intentSender) {
         onSuccessInternal(Preconditions.checkNotNull(intentSender));
@@ -73,22 +83,30 @@
         }
     }
 
+
+
+
     /**
      * Notifies the Android System that an
      * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} could not be handled
      * by the service.
      *
-     * <p>This method should only be called when the service could not handle the request right away
-     * and could not recover or retry it. If the service could retry or recover, it could keep
-     * the {@link SaveRequest} and call {@link #onSuccess()} instead.
+     * <p>This method is just used for logging purposes, the Android System won't call the service
+     * again in case of failures&mdash;if you need to recover from the failure, just save the
+     * {@link SaveRequest} and try again later.
      *
-     * <p><b>Note:</b> The Android System displays an UI with the supplied error message; if
-     * you prefer to show your own message, call {@link #onSuccess()} or
-     * {@link #onSuccess(IntentSender)} instead.
+     * <p><b>Note: </b>for apps targeting {@link android.os.Build.VERSION_CODES#Q} or higher, this
+     * method just logs the message on {@code logcat}; for apps targetting older SDKs, it also
+     * displays the message to user using a {@link android.widget.Toast}.
      *
-     * @param message error message to be displayed to the user.
+     * @param message error message. <b>Note: </b> this message should <b>not</b> contain PII
+     * (Personally Identifiable Information, such as username or email address).
+     *
+     * @throws IllegalStateException if this method, {@link #onSuccess()},
+     * or {@link #onSuccess(IntentSender)} was already called.
      */
     public void onFailure(CharSequence message) {
+        Log.w(TAG, "onFailure(): " + message);
         assertNotCalled();
         mCalled = true;
         try {
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 26240c5..c1a3c2b 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -283,6 +283,9 @@
                         } catch (android.os.RemoteException ex) {
                             Log.v(TAG, "Unable to contact notification manager", ex);
                             throw ex.rethrowFromSystemServer();
+                        } catch (SecurityException e) {
+                            // app cannot catch and recover from this, so do on their behalf
+                            Log.w(TAG, "Enqueue adjustment failed; no longer connected", e);
                         }
                     }
                     break;
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index e819c96..37a9b10 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -146,6 +146,7 @@
     private static final String RULE_ATT_CONDITION_ID = "conditionId";
     private static final String RULE_ATT_CREATION_TIME = "creationTime";
     private static final String RULE_ATT_ENABLER = "enabler";
+    private static final String RULE_ATT_MODIFIED = "modified";
 
     @UnsupportedAppUsage
     public boolean allowAlarms = DEFAULT_ALLOW_ALARMS;
@@ -472,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();
@@ -633,6 +643,7 @@
             Slog.i(TAG, "Updating zenMode of automatic rule " + rt.name);
             rt.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         }
+        rt.modified = safeBoolean(parser, RULE_ATT_MODIFIED, false);
         return rt;
     }
 
@@ -656,6 +667,7 @@
         if (rule.condition != null) {
             writeConditionXml(rule.condition, out);
         }
+        out.attribute(null, RULE_ATT_MODIFIED, Boolean.toString(rule.modified));
     }
 
     public static Condition readConditionXml(XmlPullParser parser) {
@@ -1285,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();
     }
@@ -1303,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;
     }
@@ -1321,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
@@ -1334,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;
         }
 
@@ -1456,6 +1474,7 @@
         public long creationTime;        // required for automatic
         public String enabler;          // package name, only used for manual rules.
         public ZenPolicy zenPolicy;
+        public boolean modified;    // rule has been modified from initial creation
 
         public ZenRule() { }
 
@@ -1477,6 +1496,7 @@
                 enabler = source.readString();
             }
             zenPolicy = source.readParcelable(null);
+            modified = source.readInt() == 1;
         }
 
         @Override
@@ -1512,6 +1532,7 @@
                 dest.writeInt(0);
             }
             dest.writeParcelable(zenPolicy, 0);
+            dest.writeInt(modified ? 1 : 0);
         }
 
         @Override
@@ -1528,6 +1549,7 @@
                     .append(",creationTime=").append(creationTime)
                     .append(",enabler=").append(enabler)
                     .append(",zenPolicy=").append(zenPolicy)
+                    .append(",modified=").append(modified)
                     .append(']').toString();
         }
 
@@ -1554,6 +1576,7 @@
             if (zenPolicy != null) {
                 zenPolicy.writeToProto(proto, ZenRuleProto.ZEN_POLICY);
             }
+            proto.write(ZenRuleProto.MODIFIED, modified);
             proto.end(token);
         }
 
@@ -1606,6 +1629,9 @@
             if (!Objects.equals(zenPolicy, to.zenPolicy)) {
                 d.addLine(item, "zenPolicy", zenPolicy, to.zenPolicy);
             }
+            if (modified != to.modified) {
+                d.addLine(item, "modified", modified, to.modified);
+            }
         }
 
         @Override
@@ -1622,13 +1648,14 @@
                     && Objects.equals(other.component, component)
                     && Objects.equals(other.id, id)
                     && Objects.equals(other.enabler, enabler)
-                    && Objects.equals(other.zenPolicy, zenPolicy);
+                    && Objects.equals(other.zenPolicy, zenPolicy)
+                    && other.modified == modified;
         }
 
         @Override
         public int hashCode() {
             return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
-                    component, id, enabler, zenPolicy);
+                    component, id, enabler, zenPolicy, modified);
         }
 
         public boolean isAutomaticActive() {
diff --git a/core/java/android/service/voice/IVoiceInteractionService.aidl b/core/java/android/service/voice/IVoiceInteractionService.aidl
index e3d68a6..24819a6 100644
--- a/core/java/android/service/voice/IVoiceInteractionService.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionService.aidl
@@ -16,6 +16,8 @@
 
 package android.service.voice;
 
+import com.android.internal.app.IVoiceActionCheckCallback;
+
 /**
  * @hide
  */
@@ -24,4 +26,6 @@
     void soundModelsChanged();
     void shutdown();
     void launchVoiceAssistFromKeyguard();
+    void getActiveServiceSupportedActions(in List<String> voiceActions,
+     in IVoiceActionCheckCallback callback);
 }
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 0bbc07e..e105fdf 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -16,6 +16,8 @@
 
 package android.service.voice;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.UnsupportedAppUsage;
 import android.app.Service;
@@ -26,17 +28,22 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
+import android.util.ArraySet;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.IVoiceActionCheckCallback;
 import com.android.internal.app.IVoiceInteractionManagerService;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
 /**
  * Top-level service of the current global voice interactor, which is providing
@@ -71,23 +78,43 @@
     public static final String SERVICE_META_DATA = "android.voice_interaction";
 
     IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
-        @Override public void ready() {
-            mHandler.sendEmptyMessage(MSG_READY);
-        }
-        @Override public void shutdown() {
-            mHandler.sendEmptyMessage(MSG_SHUTDOWN);
-        }
-        @Override public void soundModelsChanged() {
-            mHandler.sendEmptyMessage(MSG_SOUND_MODELS_CHANGED);
-        }
         @Override
-        public void launchVoiceAssistFromKeyguard() throws RemoteException {
-            mHandler.sendEmptyMessage(MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD);
+        public void ready() {
+            Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+                    VoiceInteractionService::onReady, VoiceInteractionService.this));
+        }
+
+        @Override
+        public void shutdown() {
+            Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+                    VoiceInteractionService::onShutdownInternal, VoiceInteractionService.this));
+        }
+
+        @Override
+        public void soundModelsChanged() {
+            Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+                    VoiceInteractionService::onSoundModelsChangedInternal,
+                    VoiceInteractionService.this));
+        }
+
+        @Override
+        public void launchVoiceAssistFromKeyguard() {
+            Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+                    VoiceInteractionService::onLaunchVoiceAssistFromKeyguard,
+                    VoiceInteractionService.this));
+        }
+
+        @Override
+        public void getActiveServiceSupportedActions(List<String> voiceActions,
+                IVoiceActionCheckCallback callback) {
+            Handler.getMain().executeOrSendMessage(
+                    PooledLambda.obtainMessage(VoiceInteractionService::onHandleVoiceActionCheck,
+                            VoiceInteractionService.this,
+                            voiceActions,
+                            callback));
         }
     };
 
-    MyHandler mHandler;
-
     IVoiceInteractionManagerService mSystemService;
 
     private final Object mLock = new Object();
@@ -96,33 +123,6 @@
 
     private AlwaysOnHotwordDetector mHotwordDetector;
 
-    static final int MSG_READY = 1;
-    static final int MSG_SHUTDOWN = 2;
-    static final int MSG_SOUND_MODELS_CHANGED = 3;
-    static final int MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD = 4;
-
-    class MyHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_READY:
-                    onReady();
-                    break;
-                case MSG_SHUTDOWN:
-                    onShutdownInternal();
-                    break;
-                case MSG_SOUND_MODELS_CHANGED:
-                    onSoundModelsChangedInternal();
-                    break;
-                case MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD:
-                    onLaunchVoiceAssistFromKeyguard();
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-    }
-
     /**
      * Called when a user has activated an affordance to launch voice assist from the Keyguard.
      *
@@ -186,7 +186,7 @@
      * be any combination of
      * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
      * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
-      * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
+     * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
      * to request that the system generate and deliver assist data on the current foreground
      * app as part of showing the session UI.
      */
@@ -200,10 +200,22 @@
         }
     }
 
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mHandler = new MyHandler();
+    /**
+     * Request to query for what extended voice actions this service supports. This method will
+     * be called when the system checks the supported actions of this
+     * {@link VoiceInteractionService}. Supported actions may be delivered to
+     * {@link VoiceInteractionSession} later to request a session to perform an action.
+     *
+     * <p>Voice actions are defined in support libraries and could vary based on platform context.
+     * For example, car related voice actions will be defined in car support libraries.
+     *
+     * @param voiceActions A set of checked voice actions.
+     * @return Returns a subset of checked voice actions. Additional voice actions in the
+     * returned set will be ignored. Returns null or empty set if no actions are supported.
+     */
+    @Nullable
+    public Set<String> onGetSupportedVoiceActions(@NonNull Set<String> voiceActions) {
+        return null;
     }
 
     @Override
@@ -254,6 +266,18 @@
         }
     }
 
+    private void onHandleVoiceActionCheck(List<String> voiceActions,
+            IVoiceActionCheckCallback callback) {
+        if (callback != null) {
+            try {
+                Set<String> voiceActionsSet = new ArraySet<>(voiceActions);
+                Set<String> resultSet = onGetSupportedVoiceActions(voiceActionsSet);
+                callback.onComplete(resultSet == null ? null : new ArrayList<>(resultSet));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
     /**
      * Creates an {@link AlwaysOnHotwordDetector} for the given keyphrase and locale.
      * This instance must be retained and used by the client.
@@ -289,12 +313,12 @@
     }
 
     /**
-      * Checks if a given keyphrase and locale are supported to create an
-      * {@link AlwaysOnHotwordDetector}.
-      *
-      * @return true if the keyphrase and locale combination is supported, false otherwise.
-      * @hide
-      */
+     * Checks if a given keyphrase and locale are supported to create an
+     * {@link AlwaysOnHotwordDetector}.
+     *
+     * @return true if the keyphrase and locale combination is supported, false otherwise.
+     * @hide
+     */
     @UnsupportedAppUsage
     public final boolean isKeyphraseAndLocaleSupportedForHotword(String keyphrase, Locale locale) {
         if (mKeyphraseEnrollmentInfo == null) {
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 26223f7..163e3d5 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -115,6 +115,12 @@
      */
     public static final int SHOW_SOURCE_PUSH_TO_TALK = 1 << 5;
 
+    /**
+     * Flag for use with {@link #onShow}: indicates that the voice interaction service was invoked
+     * from a notification.
+     */
+    public static final int SHOW_SOURCE_NOTIFICATION = 1 << 6;
+
     final Context mContext;
     final HandlerCaller mHandlerCaller;
 
diff --git a/core/java/android/text/GraphicsOperations.java b/core/java/android/text/GraphicsOperations.java
index 6edf845..6c15446 100644
--- a/core/java/android/text/GraphicsOperations.java
+++ b/core/java/android/text/GraphicsOperations.java
@@ -58,6 +58,6 @@
     /**
      * Just like {@link Paint#getTextRunCursor}.
      */
-    int getTextRunCursor(int contextStart, int contextEnd, int dir, int offset,
+    int getTextRunCursor(int contextStart, int contextEnd, boolean isRtl, int offset,
             int cursorOpt, Paint p);
 }
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 33c977b..c89617f 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -619,7 +619,7 @@
                     previousLineBottom = lbottom;
                     int lbaseline = lbottom - getLineDescent(i);
 
-                    if (start >= spanEnd) {
+                    if (end >= spanEnd) {
                         // These should be infrequent, so we'll use this so that
                         // we don't have to check as often.
                         spanEnd = mLineBackgroundSpans.getNextTransition(start, textLength);
diff --git a/core/java/android/text/NativeLineBreaker.java b/core/java/android/text/NativeLineBreaker.java
index 2bcfa5f..94e10e8 100644
--- a/core/java/android/text/NativeLineBreaker.java
+++ b/core/java/android/text/NativeLineBreaker.java
@@ -21,6 +21,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.Px;
 
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
@@ -258,16 +259,91 @@
     /**
      * A result object of a line breaking
      */
-    public static class LineBreaks {
-        public int breakCount;
-        private static final int INITIAL_SIZE = 16;
-        public int[] breaks = new int[INITIAL_SIZE];
-        public float[] widths = new float[INITIAL_SIZE];
-        public float[] ascents = new float[INITIAL_SIZE];
-        public float[] descents = new float[INITIAL_SIZE];
-        // TODO: Introduce Hyphenator for explaining the meaning of flags.
-        public int[] flags = new int[INITIAL_SIZE];
-        // breaks, widths, and flags should all have the same length
+    public static class Result {
+        // Following two contstant must be synced with minikin's line breaker.
+        private static final int TAB_MASK = 0x20000000;
+        private static final int HYPHEN_MASK = 0xFF;
+
+        private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                Result.class.getClassLoader(), nGetReleaseResultFunc(), 32);
+        private final long mPtr;
+
+        private Result(long ptr) {
+            mPtr = ptr;
+            sRegistry.registerNativeAllocation(this, mPtr);
+        }
+
+        /**
+         * Returns a number of line count.
+         *
+         * @return number of lines
+         */
+        public @IntRange(from = 0) int getLineCount() {
+            return nGetLineCount(mPtr);
+        }
+
+        /**
+         * Returns a break offset of the line.
+         *
+         * @param lineIndex an index of the line.
+         * @return the break offset.
+         */
+        public @IntRange(from = 0) int getLineBreakOffset(@IntRange(from = 0) int lineIndex) {
+            return nGetLineBreakOffset(mPtr, lineIndex);
+        }
+
+        /**
+         * Returns a width of the line in pixels.
+         *
+         * @param lineIndex an index of the line.
+         * @return a width of the line in pixexls
+         */
+        public @Px float getLineWidth(@IntRange(from = 0) int lineIndex) {
+            return nGetLineWidth(mPtr, lineIndex);
+        }
+
+        /**
+         * Returns an entier font ascent of the line in pixels.
+         *
+         * @param lineIndex an index of the line.
+         * @return an entier font ascent of the line in pixels.
+         */
+        public @Px float getLineAscent(@IntRange(from = 0) int lineIndex) {
+            return nGetLineAscent(mPtr, lineIndex);
+        }
+
+        /**
+         * Returns an entier font descent of the line in pixels.
+         *
+         * @param lineIndex an index of the line.
+         * @return an entier font descent of the line in pixels.
+         */
+        public @Px float getLineDescent(@IntRange(from = 0) int lineIndex) {
+            return nGetLineDescent(mPtr, lineIndex);
+        }
+
+        /**
+         * Returns true if the line has a TAB character.
+         *
+         * @param lineIndex an index of the line.
+         * @return true if the line has a TAB character
+         */
+        public boolean hasLineTab(int lineIndex) {
+            return (nGetLineFlag(mPtr, lineIndex) & TAB_MASK) != 0;
+        }
+
+        /**
+         * Returns a packed packed hyphen edit for the line.
+         *
+         * @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)
+         */
+        public int getLineHyphenEdit(int lineIndex) {
+            return (nGetLineFlag(mPtr, lineIndex) & HYPHEN_MASK);
+        }
     }
 
     private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
@@ -294,14 +370,12 @@
      * @param measuredPara a result of the text measurement
      * @param constraints for a single paragraph
      * @param lineNumber a line number of this paragraph
-     * @param out object to set line break information for the given paragraph
      */
-    public void computeLineBreaks(
+    public Result computeLineBreaks(
             @NonNull NativeMeasuredParagraph measuredPara,
             @NonNull ParagraphConstraints constraints,
-            @IntRange(from = 0) int lineNumber,
-            @NonNull LineBreaks out) {
-        out.breakCount = nComputeLineBreaks(
+            @IntRange(from = 0) int lineNumber) {
+        return new Result(nComputeLineBreaks(
                 mNativePtr,
 
                 // Inputs
@@ -313,17 +387,7 @@
                 constraints.mWidth,
                 constraints.mVariableTabStops,
                 constraints.mDefaultTabStop,
-                lineNumber,
-
-                // Outputs
-                out,
-                out.breaks.length,
-                out.breaks,
-                out.widths,
-                out.ascents,
-                out.descents,
-                out.flags);
-
+                lineNumber));
     }
 
     @FastNative
@@ -341,7 +405,7 @@
     // arrays do not have to be resized
     // The individual character widths will be returned in charWidths. The length of
     // charWidths must be at least the length of the text.
-    private static native int nComputeLineBreaks(
+    private static native long nComputeLineBreaks(
             /* non zero */ long nativePtr,
 
             // Inputs
@@ -353,14 +417,21 @@
             @FloatRange(from = 0.0f) float restWidth,
             @Nullable int[] variableTabStops,
             int defaultTabStop,
-            @IntRange(from = 0) int indentsOffset,
+            @IntRange(from = 0) int indentsOffset);
 
-            // Outputs
-            @NonNull LineBreaks recycle,
-            @IntRange(from  = 0) int recycleLength,
-            @NonNull int[] recycleBreaks,
-            @NonNull float[] recycleWidths,
-            @NonNull float[] recycleAscents,
-            @NonNull float[] recycleDescents,
-            @NonNull int[] recycleFlags);
+    // Result accessors
+    @CriticalNative
+    private static native int nGetLineCount(long ptr);
+    @CriticalNative
+    private static native int nGetLineBreakOffset(long ptr, int idx);
+    @CriticalNative
+    private static native float nGetLineWidth(long ptr, int idx);
+    @CriticalNative
+    private static native float nGetLineAscent(long ptr, int idx);
+    @CriticalNative
+    private static native float nGetLineDescent(long ptr, int idx);
+    @CriticalNative
+    private static native int nGetLineFlag(long ptr, int idx);
+    @CriticalNative
+    private static native long nGetReleaseResultFunc();
 }
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 9d841e8..0d29da0 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -1551,7 +1551,7 @@
      *
      * @param contextStart the start index of the context
      * @param contextEnd the (non-inclusive) end index of the context
-     * @param dir either DIRECTION_RTL or DIRECTION_LTR
+     * @param dir 1 if the run is RTL, otherwise 0
      * @param offset the cursor position to move from
      * @param cursorOpt how to move the cursor, one of CURSOR_AFTER,
      * CURSOR_AT_OR_AFTER, CURSOR_BEFORE,
@@ -1563,21 +1563,28 @@
     @Deprecated
     public int getTextRunCursor(int contextStart, int contextEnd, int dir, int offset,
             int cursorOpt, Paint p) {
+        return getTextRunCursor(contextStart, contextEnd, dir == 1, offset, cursorOpt, p);
+    }
+
+    /** @hide */
+    @Override
+    public int getTextRunCursor(int contextStart, int contextEnd, boolean isRtl, int offset,
+            int cursorOpt, Paint p) {
 
         int ret;
 
         int contextLen = contextEnd - contextStart;
         if (contextEnd <= mGapStart) {
             ret = p.getTextRunCursor(mText, contextStart, contextLen,
-                    dir, offset, cursorOpt);
+                    isRtl, offset, cursorOpt);
         } else if (contextStart >= mGapStart) {
             ret = p.getTextRunCursor(mText, contextStart + mGapLength, contextLen,
-                    dir, offset + mGapLength, cursorOpt) - mGapLength;
+                    isRtl, offset + mGapLength, cursorOpt) - mGapLength;
         } else {
             char[] buf = TextUtils.obtain(contextLen);
             getChars(contextStart, contextEnd, buf, 0);
             ret = p.getTextRunCursor(buf, 0, contextLen,
-                    dir, offset - contextStart, cursorOpt) + contextStart;
+                    isRtl, offset - contextStart, cursorOpt) + contextStart;
             TextUtils.recycle(buf);
         }
 
@@ -1603,13 +1610,14 @@
     public boolean equals(Object o) {
         if (o instanceof Spanned &&
                 toString().equals(o.toString())) {
-            Spanned other = (Spanned) o;
+            final Spanned other = (Spanned) o;
             // Check span data
-            Object[] otherSpans = other.getSpans(0, other.length(), Object.class);
+            final Object[] otherSpans = other.getSpans(0, other.length(), Object.class);
+            final Object[] thisSpans = getSpans(0, length(), Object.class);
             if (mSpanCount == otherSpans.length) {
                 for (int i = 0; i < mSpanCount; ++i) {
-                    Object thisSpan = mSpans[i];
-                    Object otherSpan = otherSpans[i];
+                    final Object thisSpan = thisSpans[i];
+                    final Object otherSpan = otherSpans[i];
                     if (thisSpan == this) {
                         if (other != otherSpan ||
                                 getSpanStart(thisSpan) != other.getSpanStart(otherSpan) ||
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index 7acd539..a986633 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -16,12 +16,13 @@
 
 package android.text;
 
+import android.annotation.UnsupportedAppUsage;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
 import libcore.util.EmptyArray;
 
-import android.annotation.UnsupportedAppUsage;
 import java.lang.reflect.Array;
 
 /* package */ abstract class SpannableStringInternal
@@ -502,13 +503,14 @@
     public boolean equals(Object o) {
         if (o instanceof Spanned &&
                 toString().equals(o.toString())) {
-            Spanned other = (Spanned) o;
+            final Spanned other = (Spanned) o;
             // Check span data
-            Object[] otherSpans = other.getSpans(0, other.length(), Object.class);
+            final Object[] otherSpans = other.getSpans(0, other.length(), Object.class);
+            final Object[] thisSpans = getSpans(0, length(), Object.class);
             if (mSpanCount == otherSpans.length) {
                 for (int i = 0; i < mSpanCount; ++i) {
-                    Object thisSpan = mSpans[i];
-                    Object otherSpan = otherSpans[i];
+                    final Object thisSpan = thisSpans[i];
+                    final Object otherSpan = otherSpans[i];
                     if (thisSpan == this) {
                         if (other != otherSpan ||
                                 getSpanStart(thisSpan) != other.getSpanStart(otherSpan) ||
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index e1ffef0..d2f0853 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -599,7 +599,14 @@
         float ellipsizedWidth = b.mEllipsizedWidth;
         TextUtils.TruncateAt ellipsize = b.mEllipsize;
         final boolean addLastLineSpacing = b.mAddLastLineLineSpacing;
-        NativeLineBreaker.LineBreaks lineBreaks = new NativeLineBreaker.LineBreaks();
+
+        int lineBreakCapacity = 0;
+        int[] breaks = null;
+        float[] lineWidths = null;
+        float[] ascents = null;
+        float[] descents = null;
+        boolean[] hasTabs = null;
+        int[] hyphenEdits = null;
 
         mLineCount = 0;
         mEllipsized = false;
@@ -732,14 +739,27 @@
             constraints.setIndent(firstWidth, firstWidthLineCount);
             constraints.setTabStops(variableTabStops, TAB_INCREMENT);
 
-            lineBreaker.computeLineBreaks(measuredPara.getNativeMeasuredParagraph(),
-                    constraints, mLineCount, lineBreaks);
-            int breakCount = lineBreaks.breakCount;
-            final int[] breaks = lineBreaks.breaks;
-            final float[] lineWidths = lineBreaks.widths;
-            final float[] ascents = lineBreaks.ascents;
-            final float[] descents = lineBreaks.descents;
-            final int[] flags = lineBreaks.flags;
+            NativeLineBreaker.Result res = lineBreaker.computeLineBreaks(
+                    measuredPara.getNativeMeasuredParagraph(), constraints, mLineCount);
+            int breakCount = res.getLineCount();
+            if (lineBreakCapacity < breakCount) {
+                lineBreakCapacity = breakCount;
+                breaks = new int[lineBreakCapacity];
+                lineWidths = new float[lineBreakCapacity];
+                ascents = new float[lineBreakCapacity];
+                descents = new float[lineBreakCapacity];
+                hasTabs = new boolean[lineBreakCapacity];
+                hyphenEdits = new int[lineBreakCapacity];
+            }
+
+            for (int i = 0; i < breakCount; ++i) {
+                breaks[i] = res.getLineBreakOffset(i);
+                lineWidths[i] = res.getLineWidth(i);
+                ascents[i] = res.getLineAscent(i);
+                descents[i] = res.getLineDescent(i);
+                hasTabs[i] = res.hasLineTab(i);
+                hyphenEdits[i] = res.getLineHyphenEdit(i);
+            }
 
             final int remainingLineCount = mMaximumVisibleLineCount - mLineCount;
             final boolean ellipsisMayBeApplied = ellipsize != null
@@ -750,7 +770,7 @@
                     && ellipsisMayBeApplied) {
                 // Calculate width
                 float width = 0;
-                int flag = 0;  // XXX May need to also have starting hyphen edit
+                boolean hasTab = false;  // XXX May need to also have starting hyphen edit
                 for (int i = remainingLineCount - 1; i < breakCount; i++) {
                     if (i == breakCount - 1) {
                         width += lineWidths[i];
@@ -759,12 +779,12 @@
                             width += measuredPara.getCharWidthAt(j - paraStart);
                         }
                     }
-                    flag |= flags[i] & TAB_MASK;
+                    hasTab |= hasTabs[i];
                 }
                 // Treat the last line and overflowed lines as a single line.
                 breaks[remainingLineCount - 1] = breaks[breakCount - 1];
                 lineWidths[remainingLineCount - 1] = width;
-                flags[remainingLineCount - 1] = flag;
+                hasTabs[remainingLineCount - 1] = hasTab;
 
                 breakCount = remainingLineCount;
             }
@@ -821,8 +841,8 @@
                     v = out(source, here, endPos,
                             ascent, descent, fmTop, fmBottom,
                             v, spacingmult, spacingadd, chooseHt, chooseHtv, fm,
-                            flags[breakIndex], needMultiply, measuredPara, bufEnd,
-                            includepad, trackpad, addLastLineSpacing, chs,
+                            hasTabs[breakIndex], hyphenEdits[breakIndex], needMultiply,
+                            measuredPara, bufEnd, includepad, trackpad, addLastLineSpacing, chs,
                             paraStart, ellipsize, ellipsizedWidth, lineWidths[breakIndex],
                             paint, moreChars);
 
@@ -860,7 +880,7 @@
                     fm.top, fm.bottom,
                     v,
                     spacingmult, spacingadd, null,
-                    null, fm, 0,
+                    null, fm, false, 0,
                     needMultiply, measuredPara, bufEnd,
                     includepad, trackpad, addLastLineSpacing, null,
                     bufStart, ellipsize,
@@ -871,7 +891,8 @@
     private int out(final CharSequence text, final int start, final int end, int above, int below,
             int top, int bottom, int v, final float spacingmult, final float spacingadd,
             final LineHeightSpan[] chooseHt, final int[] chooseHtv, final Paint.FontMetricsInt fm,
-            final int flags, final boolean needMultiply, @NonNull final MeasuredParagraph measured,
+            final boolean hasTab, final int hyphenEdit, final boolean needMultiply,
+            @NonNull final MeasuredParagraph measured,
             final int bufEnd, final boolean includePad, final boolean trackPad,
             final boolean addLastLineLineSpacing, final char[] chs,
             final int widthStart, final TextUtils.TruncateAt ellipsize, final float ellipsisWidth,
@@ -1005,8 +1026,8 @@
 
         // TODO: could move TAB to share same column as HYPHEN, simplifying this code and gaining
         // one bit for start field
-        lines[off + TAB] |= flags & TAB_MASK;
-        lines[off + HYPHEN] = flags;
+        lines[off + TAB] |= hasTab ? TAB_MASK : 0;
+        lines[off + HYPHEN] = hyphenEdit;
         lines[off + DIR] |= dir << DIR_SHIFT;
         mLineDirections[j] = measured.getDirections(start - widthStart, end - widthStart);
 
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index ad7a851..44dfd11 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -802,14 +802,13 @@
             }
         }
 
-        int dir = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR;
         int cursorOpt = after ? Paint.CURSOR_AFTER : Paint.CURSOR_BEFORE;
         if (mCharsValid) {
             return wp.getTextRunCursor(mChars, spanStart, spanLimit - spanStart,
-                    dir, offset, cursorOpt);
+                    runIsRtl, offset, cursorOpt);
         } else {
             return wp.getTextRunCursor(mText, mStart + spanStart,
-                    mStart + spanLimit, dir, mStart + offset, cursorOpt) - mStart;
+                    mStart + spanLimit, runIsRtl, mStart + offset, cursorOpt) - mStart;
         }
     }
 
@@ -1231,7 +1230,7 @@
                     // with the next chunk. So we just save the TextPaint for future comparisons
                     // and use.
                     activePaint.set(wp);
-                } else if (!wp.hasEqualAttributes(activePaint)) {
+                } else if (!equalAttributes(wp, activePaint)) {
                     // The style of the present chunk of text is substantially different from the
                     // style of the previous chunk. We need to handle the active piece of text
                     // and restart with the present chunk.
@@ -1336,4 +1335,42 @@
     }
 
     private static final int TAB_INCREMENT = 20;
+
+    private static boolean equalAttributes(@NonNull TextPaint lp, @NonNull TextPaint rp) {
+        return lp.getColorFilter() == rp.getColorFilter()
+                && lp.getMaskFilter() == rp.getMaskFilter()
+                && lp.getShader() == rp.getShader()
+                && lp.getTypeface() == rp.getTypeface()
+                && lp.getXfermode() == rp.getXfermode()
+                && lp.getTextLocales().equals(rp.getTextLocales())
+                && TextUtils.equals(lp.getFontFeatureSettings(), rp.getFontFeatureSettings())
+                && TextUtils.equals(lp.getFontVariationSettings(), rp.getFontVariationSettings())
+                && lp.getShadowLayerRadius() == rp.getShadowLayerRadius()
+                && lp.getShadowLayerDx() == rp.getShadowLayerDx()
+                && lp.getShadowLayerDy() == rp.getShadowLayerDy()
+                && lp.getShadowLayerColor() == rp.getShadowLayerColor()
+                && lp.getFlags() == rp.getFlags()
+                && lp.getHinting() == rp.getHinting()
+                && lp.getStyle() == rp.getStyle()
+                && lp.getColor() == rp.getColor()
+                && lp.getStrokeWidth() == rp.getStrokeWidth()
+                && lp.getStrokeMiter() == rp.getStrokeMiter()
+                && lp.getStrokeCap() == rp.getStrokeCap()
+                && lp.getStrokeJoin() == rp.getStrokeJoin()
+                && lp.getTextAlign() == rp.getTextAlign()
+                && lp.isElegantTextHeight() == rp.isElegantTextHeight()
+                && lp.getTextSize() == rp.getTextSize()
+                && lp.getTextScaleX() == rp.getTextScaleX()
+                && lp.getTextSkewX() == rp.getTextSkewX()
+                && lp.getLetterSpacing() == rp.getLetterSpacing()
+                && lp.getWordSpacing() == rp.getWordSpacing()
+                && lp.getHyphenEdit() == rp.getHyphenEdit()
+                && lp.bgColor == rp.bgColor
+                && lp.baselineShift == rp.baselineShift
+                && lp.linkColor == rp.linkColor
+                && lp.drawableState == rp.drawableState
+                && lp.density == rp.density
+                && lp.underlineColor == rp.underlineColor
+                && lp.underlineThickness == rp.underlineThickness;
+    }
 }
diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java
index 7bcc685..d5aad33 100644
--- a/core/java/android/text/TextPaint.java
+++ b/core/java/android/text/TextPaint.java
@@ -17,7 +17,7 @@
 package android.text;
 
 import android.annotation.ColorInt;
-import android.annotation.NonNull;
+import android.annotation.Px;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Paint;
 
@@ -37,17 +37,14 @@
     public float density = 1.0f;
     /**
      * Special value 0 means no custom underline
-     * @hide
      */
     @ColorInt
-    @UnsupportedAppUsage
     public int underlineColor = 0;
+
     /**
      * Thickness of the underline, in pixels.
-     * @hide
      */
-    @UnsupportedAppUsage
-    public float underlineThickness;
+    public @Px float underlineThickness;
 
     public TextPaint() {
         super();
@@ -78,24 +75,6 @@
     }
 
     /**
-     * Returns true if all attributes, including the attributes inherited from Paint, are equal.
-     *
-     * The caller is expected to have checked the trivial cases, like the pointers being equal,
-     * the objects having different classes, or the parameter being null.
-     * @hide
-     */
-    public boolean hasEqualAttributes(@NonNull TextPaint other) {
-        return bgColor == other.bgColor
-                && baselineShift == other.baselineShift
-                && linkColor == other.linkColor
-                && drawableState == other.drawableState
-                && density == other.density
-                && underlineColor == other.underlineColor
-                && underlineThickness == other.underlineThickness
-                && super.hasEqualAttributes((Paint) other);
-    }
-
-    /**
      * Defines a custom underline for this Paint.
      * @param color underline solid color
      * @param thickness underline thickness
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 5f0a46d..d4bcd12 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -310,7 +310,7 @@
             return len;
         }
 
-        offset = paint.getTextRunCursor(text, offset, len, Paint.DIRECTION_LTR /* not used */,
+        offset = paint.getTextRunCursor(text, offset, len, false /* LTR, not used */,
                 offset, Paint.CURSOR_AFTER);
 
         return adjustReplacementSpan(text, offset, false /* move to the end */);
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index c17cfd5..2dc4f60 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -16,11 +16,13 @@
 
 package android.text.style;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
 import android.graphics.LeakyTypefaceStorage;
 import android.graphics.Typeface;
+import android.graphics.fonts.Font;
 import android.os.Parcel;
 import android.text.ParcelableSpan;
 import android.text.TextPaint;
@@ -38,6 +40,21 @@
     private final ColorStateList mTextColorLink;
     private final Typeface mTypeface;
 
+    private final int mTextFontWeight;
+
+    private final float mShadowRadius;
+    private final float mShadowDx;
+    private final float mShadowDy;
+    private final int mShadowColor;
+
+    private final boolean mHasElegantTextHeight;
+    private final boolean mElegantTextHeight;
+    private final boolean mHasLetterSpacing;
+    private final float mLetterSpacing;
+
+    private final String mFontFeatureSettings;
+    private final String mFontVariationSettings;
+
     /**
      * Uses the specified TextAppearance resource to determine the
      * text appearance.  The <code>appearance</code> should be, for example,
@@ -104,6 +121,34 @@
             }
         }
 
+        mTextFontWeight = a.getInt(com.android.internal.R.styleable
+                .TextAppearance_textFontWeight, -1);
+
+        mShadowRadius = a.getFloat(com.android.internal.R.styleable
+                .TextAppearance_shadowRadius, 0.0f);
+        mShadowDx = a.getFloat(com.android.internal.R.styleable
+                .TextAppearance_shadowDx, 0.0f);
+        mShadowDy = a.getFloat(com.android.internal.R.styleable
+                .TextAppearance_shadowDy, 0.0f);
+        mShadowColor = a.getInt(com.android.internal.R.styleable
+                .TextAppearance_shadowColor, 0);
+
+        mHasElegantTextHeight = a.hasValue(com.android.internal.R.styleable
+                .TextAppearance_elegantTextHeight);
+        mElegantTextHeight = a.getBoolean(com.android.internal.R.styleable
+                .TextAppearance_elegantTextHeight, false);
+
+        mHasLetterSpacing = a.hasValue(com.android.internal.R.styleable
+                .TextAppearance_letterSpacing);
+        mLetterSpacing = a.getFloat(com.android.internal.R.styleable
+                .TextAppearance_letterSpacing, 0.0f);
+
+        mFontFeatureSettings = a.getString(com.android.internal.R.styleable
+                .TextAppearance_fontFeatureSettings);
+
+        mFontVariationSettings = a.getString(com.android.internal.R.styleable
+                .TextAppearance_fontVariationSettings);
+
         a.recycle();
 
         if (colorList >= 0) {
@@ -129,6 +174,21 @@
         mTextColor = color;
         mTextColorLink = linkColor;
         mTypeface = null;
+
+        mTextFontWeight = -1;
+
+        mShadowRadius = 0.0f;
+        mShadowDx = 0.0f;
+        mShadowDy = 0.0f;
+        mShadowColor = 0;
+
+        mHasElegantTextHeight = false;
+        mElegantTextHeight = false;
+        mHasLetterSpacing = false;
+        mLetterSpacing = 0.0f;
+
+        mFontFeatureSettings = null;
+        mFontVariationSettings = null;
     }
 
     public TextAppearanceSpan(Parcel src) {
@@ -146,6 +206,21 @@
             mTextColorLink = null;
         }
         mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src);
+
+        mTextFontWeight = src.readInt();
+
+        mShadowRadius = src.readFloat();
+        mShadowDx = src.readFloat();
+        mShadowDy = src.readFloat();
+        mShadowColor = src.readInt();
+
+        mHasElegantTextHeight = src.readBoolean();
+        mElegantTextHeight = src.readBoolean();
+        mHasLetterSpacing = src.readBoolean();
+        mLetterSpacing = src.readFloat();
+
+        mFontFeatureSettings = src.readString();
+        mFontVariationSettings = src.readString();
     }
 
     public int getSpanTypeId() {
@@ -183,6 +258,21 @@
             dest.writeInt(0);
         }
         LeakyTypefaceStorage.writeTypefaceToParcel(mTypeface, dest);
+
+        dest.writeInt(mTextFontWeight);
+
+        dest.writeFloat(mShadowRadius);
+        dest.writeFloat(mShadowDx);
+        dest.writeFloat(mShadowDy);
+        dest.writeInt(mShadowColor);
+
+        dest.writeBoolean(mHasElegantTextHeight);
+        dest.writeBoolean(mElegantTextHeight);
+        dest.writeBoolean(mHasLetterSpacing);
+        dest.writeFloat(mLetterSpacing);
+
+        dest.writeString(mFontFeatureSettings);
+        dest.writeString(mFontVariationSettings);
     }
 
     /**
@@ -225,6 +315,81 @@
         return mStyle;
     }
 
+    /**
+     * Returns the text font weight specified by this span, or <code>-1</code>
+     * if it does not specify one.
+     */
+    public int getTextFontWeight() {
+        return mTextFontWeight;
+    }
+
+    /**
+     * Returns the typeface specified by this span, or <code>null</code>
+     * if it does not specify one.
+     */
+    @Nullable
+    public Typeface getTypeface() {
+        return mTypeface;
+    }
+
+    /**
+     * Returns the color of the text shadow specified by this span, or <code>0</code>
+     * if it does not specify one.
+     */
+    public int getShadowColor() {
+        return mShadowColor;
+    }
+
+    /**
+     * Returns the horizontal offset of the text shadow specified by this span, or <code>0.0f</code>
+     * if it does not specify one.
+     */
+    public float getShadowDx() {
+        return mShadowDx;
+    }
+
+    /**
+     * Returns the vertical offset of the text shadow specified by this span, or <code>0.0f</code>
+     * if it does not specify one.
+     */
+    public float getShadowDy() {
+        return mShadowDy;
+    }
+
+    /**
+     * Returns the blur radius of the text shadow specified by this span, or <code>0.0f</code>
+     * if it does not specify one.
+     */
+    public float getShadowRadius() {
+        return mShadowRadius;
+    }
+
+    /**
+     * Returns the font feature settings specified by this span, or <code>null</code>
+     * if it does not specify one.
+     */
+    @Nullable
+    public String getFontFeatureSettings() {
+        return mFontFeatureSettings;
+    }
+
+    /**
+     * Returns the font variation settings specified by this span, or <code>null</code>
+     * if it does not specify one.
+     */
+    @Nullable
+    public String getFontVariationSettings() {
+        return mFontVariationSettings;
+    }
+
+    /**
+     * Returns the value of elegant height metrics flag specified by this span,
+     * or <code>false</code> if it does not specify one.
+     */
+    public boolean isElegantTextHeight() {
+        return mElegantTextHeight;
+    }
+
     @Override
     public void updateDrawState(TextPaint ds) {
         updateMeasureState(ds);
@@ -236,6 +401,10 @@
         if (mTextColorLink != null) {
             ds.linkColor = mTextColorLink.getColorForState(ds.drawableState, 0);
         }
+
+        if (mShadowColor != 0) {
+            ds.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
+        }
     }
 
     @Override
@@ -267,7 +436,16 @@
         }
 
         if (styledTypeface != null) {
-            int fake = style & ~styledTypeface.getStyle();
+            final Typeface readyTypeface;
+            if (mTextFontWeight >= 0) {
+                final int weight = Math.min(Font.FONT_WEIGHT_MAX, mTextFontWeight);
+                final boolean italic = (style & Typeface.ITALIC) != 0;
+                readyTypeface = ds.setTypeface(Typeface.create(styledTypeface, weight, italic));
+            } else {
+                readyTypeface = styledTypeface;
+            }
+
+            int fake = style & ~readyTypeface.getStyle();
 
             if ((fake & Typeface.BOLD) != 0) {
                 ds.setFakeBoldText(true);
@@ -277,11 +455,27 @@
                 ds.setTextSkewX(-0.25f);
             }
 
-            ds.setTypeface(styledTypeface);
+            ds.setTypeface(readyTypeface);
         }
 
         if (mTextSize > 0) {
             ds.setTextSize(mTextSize);
         }
+
+        if (mHasElegantTextHeight) {
+            ds.setElegantTextHeight(mElegantTextHeight);
+        }
+
+        if (mHasLetterSpacing) {
+            ds.setLetterSpacing(mLetterSpacing);
+        }
+
+        if (mFontFeatureSettings != null) {
+            ds.setFontFeatureSettings(mFontFeatureSettings);
+        }
+
+        if (mFontVariationSettings != null) {
+            ds.setFontVariationSettings(mFontVariationSettings);
+        }
     }
 }
diff --git a/core/java/android/transition/ChangeImageTransform.java b/core/java/android/transition/ChangeImageTransform.java
index d7a9120..9fa9961 100644
--- a/core/java/android/transition/ChangeImageTransform.java
+++ b/core/java/android/transition/ChangeImageTransform.java
@@ -97,22 +97,13 @@
         values.put(PROPNAME_BOUNDS, bounds);
         Matrix matrix;
         ImageView.ScaleType scaleType = imageView.getScaleType();
-        if (scaleType == ImageView.ScaleType.FIT_XY) {
-            matrix = imageView.getImageMatrix();
-            if (!matrix.isIdentity()) {
-                matrix = new Matrix(matrix);
-            } else {
-                int drawableWidth = drawable.getIntrinsicWidth();
-                int drawableHeight = drawable.getIntrinsicHeight();
-                if (drawableWidth > 0 && drawableHeight > 0) {
-                    float scaleX = ((float) bounds.width()) / drawableWidth;
-                    float scaleY = ((float) bounds.height()) / drawableHeight;
-                    matrix = new Matrix();
-                    matrix.setScale(scaleX, scaleY);
-                } else {
-                    matrix = null;
-                }
-            }
+        int drawableWidth = drawable.getIntrinsicWidth();
+        int drawableHeight = drawable.getIntrinsicHeight();
+        if (scaleType == ImageView.ScaleType.FIT_XY && drawableWidth > 0 && drawableHeight > 0) {
+            float scaleX = ((float) bounds.width()) / drawableWidth;
+            float scaleY = ((float) bounds.height()) / drawableHeight;
+            matrix = new Matrix();
+            matrix.setScale(scaleX, scaleY);
         } else {
             matrix = new Matrix(imageView.getImageMatrix());
         }
@@ -152,17 +143,13 @@
         }
         Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
         Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
-        if (startBounds == null || endBounds == null) {
+        Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_MATRIX);
+        Matrix endMatrix = (Matrix) endValues.values.get(PROPNAME_MATRIX);
+        if (startBounds == null || endBounds == null || startMatrix == null || endMatrix == null) {
             return null;
         }
 
-        Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_MATRIX);
-        Matrix endMatrix = (Matrix) endValues.values.get(PROPNAME_MATRIX);
-
-        boolean matricesEqual = (startMatrix == null && endMatrix == null) ||
-                (startMatrix != null && startMatrix.equals(endMatrix));
-
-        if (startBounds.equals(endBounds) && matricesEqual) {
+        if (startBounds.equals(endBounds) && startMatrix.equals(endMatrix)) {
             return null;
         }
 
@@ -172,15 +159,9 @@
         int drawableHeight = drawable.getIntrinsicHeight();
 
         ObjectAnimator animator;
-        if (drawableWidth == 0 || drawableHeight == 0) {
+        if (drawableWidth <= 0 || drawableHeight <= 0) {
             animator = createNullAnimator(imageView);
         } else {
-            if (startMatrix == null) {
-                startMatrix = Matrix.IDENTITY_MATRIX;
-            }
-            if (endMatrix == null) {
-                endMatrix = Matrix.IDENTITY_MATRIX;
-            }
             ANIMATED_TRANSFORM_PROPERTY.set(imageView, startMatrix);
             animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
         }
@@ -189,7 +170,7 @@
 
     private ObjectAnimator createNullAnimator(ImageView imageView) {
         return ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
-                NULL_MATRIX_EVALUATOR, null, null);
+                NULL_MATRIX_EVALUATOR, Matrix.IDENTITY_MATRIX, Matrix.IDENTITY_MATRIX);
     }
 
     private ObjectAnimator createMatrixAnimator(final ImageView imageView, Matrix startMatrix,
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index f8e8762..4608e20 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -188,7 +188,13 @@
 
         final ViewGroup sceneRoot = scene.getSceneRoot();
         if (!sPendingTransitions.contains(sceneRoot)) {
+            Scene oldScene = Scene.getCurrentScene(sceneRoot);
             if (transition == null) {
+                // Notify old scene that it is being exited
+                if (oldScene != null) {
+                    oldScene.exit();
+                }
+
                 scene.enter();
             } else {
                 sPendingTransitions.add(sceneRoot);
@@ -196,7 +202,6 @@
                 Transition transitionClone = transition.clone();
                 transitionClone.setSceneRoot(sceneRoot);
 
-                Scene oldScene = Scene.getCurrentScene(sceneRoot);
                 if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
                     transitionClone.setCanRemoveViews(true);
                 }
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 5108a79..294a179 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -71,19 +71,19 @@
     /**
      * Maximum number of entries to have in array caches.
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     private static final int CACHE_SIZE = 10;
 
     /**
      * Special hash array value that indicates the container is immutable.
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     static final int[] EMPTY_IMMUTABLE_INTS = new int[0];
 
     /**
      * @hide Special immutable empty ArrayMap.
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use your own singleton empty map.
     public static final ArrayMap EMPTY = new ArrayMap<>(-1);
 
     /**
@@ -92,21 +92,21 @@
      * The first entry in the array is a pointer to the next array in the
      * list; the second entry is a pointer to the int[] hash code array for it.
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     static Object[] mBaseCache;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     static int mBaseCacheSize;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     static Object[] mTwiceBaseCache;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     static int mTwiceBaseCacheSize;
 
     final boolean mIdentityHashCode;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Hashes are an implementation detail. Use public key/value API.
     int[] mHashes;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Storage is an implementation detail. Use public key/value API.
     Object[] mArray;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use size()
     int mSize;
     MapCollections<K, V> mCollections;
 
@@ -122,7 +122,7 @@
         }
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Hashes are an implementation detail. Use indexOfKey(Object).
     int indexOf(Object key, int hash) {
         final int N = mSize;
 
@@ -161,7 +161,7 @@
         return ~end;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use indexOf(null)
     int indexOfNull() {
         final int N = mSize;
 
@@ -200,7 +200,7 @@
         return ~end;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     private void allocArrays(final int size) {
         if (mHashes == EMPTY_IMMUTABLE_INTS) {
             throw new UnsupportedOperationException("ArrayMap is immutable");
@@ -239,7 +239,7 @@
         mArray = new Object[size<<1];
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     private static void freeArrays(final int[] hashes, final Object[] array, final int size) {
         if (hashes.length == (BASE_SIZE*2)) {
             synchronized (ArrayMap.class) {
@@ -393,8 +393,15 @@
                 : indexOf(key, mIdentityHashCode ? System.identityHashCode(key) : key.hashCode());
     }
 
-    @UnsupportedAppUsage
-    int indexOfValue(Object value) {
+    /**
+     * Returns an index for which {@link #valueAt} would return the
+     * specified value, or a negative number if no keys map to the
+     * specified value.
+     * Beware that this is a linear search, unlike lookups by key,
+     * and that multiple keys can map to the same value and this will
+     * find only one of them.
+     */
+    public int indexOfValue(Object value) {
         final int N = mSize*2;
         final Object[] array = mArray;
         if (value == null) {
@@ -551,7 +558,7 @@
      * The array must already be large enough to contain the item.
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Storage is an implementation detail. Use put(K, V).
     public void append(K key, V value) {
         int index = mSize;
         final int hash = key == null ? 0
diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java
index 526a950..d74a0fe 100644
--- a/core/java/android/util/ArraySet.java
+++ b/core/java/android/util/ArraySet.java
@@ -71,15 +71,15 @@
     static int sTwiceBaseCacheSize;
 
     final boolean mIdentityHashCode;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Hashes are an implementation detail. Use public API.
     int[] mHashes;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Storage is an implementation detail. Use public API.
     Object[] mArray;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use size()
     int mSize;
     MapCollections<E, E> mCollections;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Hashes are an implementation detail. Use indexOfKey(Object).
     private int indexOf(Object key, int hash) {
         final int N = mSize;
 
@@ -118,7 +118,7 @@
         return ~end;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use indexOf(null)
     private int indexOfNull() {
         final int N = mSize;
 
@@ -157,7 +157,7 @@
         return ~end;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     private void allocArrays(final int size) {
         if (size == (BASE_SIZE * 2)) {
             synchronized (ArraySet.class) {
@@ -215,7 +215,7 @@
         mArray = new Object[size];
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Allocations are an implementation detail.
     private static void freeArrays(final int[] hashes, final Object[] array, final int size) {
         if (hashes.length == (BASE_SIZE * 2)) {
             synchronized (ArraySet.class) {
@@ -289,9 +289,10 @@
         }
     }
 
-    /** {@hide} */
-    @UnsupportedAppUsage
-    public ArraySet(Collection<E> set) {
+    /**
+     * Create a new ArraySet with items from the given collection.
+     */
+    public ArraySet(Collection<? extends E> set) {
         this();
         if (set != null) {
             addAll(set);
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/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index d5af922..af163ac 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -46,11 +46,11 @@
  * @hide
  */
 public class LongSparseLongArray implements Cloneable {
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // The type isn't even public.
     private long[] mKeys;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // The type isn't even public.
     private long[] mValues;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // The type isn't even public.
     private int mSize;
 
     /**
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index aa5ca35..89ea2d3 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -56,11 +56,11 @@
     private static final Object DELETED = new Object();
     private boolean mGarbage = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use keyAt(int)
     private int[] mKeys;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use valueAt(int), setValueAt(int, E)
     private Object[] mValues;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use size()
     private int mSize;
 
     /**
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 9c6b969..d4c4095 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -185,7 +185,9 @@
         return mValues[index];
     }
 
-    /** @hide */
+    /**
+     * Directly set the value at a particular index.
+     */
     public void setValueAt(int index, boolean value) {
         mValues[index] = value;
     }
@@ -304,10 +306,10 @@
         return buffer.toString();
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use keyAt(int)
     private int[] mKeys;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use valueAt(int), setValueAt(int, boolean)
     private boolean[] mValues;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use size()
     private int mSize;
 }
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 1954753..9e6bad1 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -46,11 +46,11 @@
  * order in the case of <code>valueAt(int)</code>.</p>
  */
 public class SparseIntArray implements Cloneable {
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use keyAt(int)
     private int[] mKeys;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use valueAt(int), setValueAt(int, int)
     private int[] mValues;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 28) // Use size()
     private int mSize;
 
     /**
@@ -191,7 +191,6 @@
 
     /**
      * Directly set the value at a particular index.
-     * @hide
      */
     public void setValueAt(int index, int value) {
         mValues[index] = value;
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
index 533d725..1bbef8e 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
@@ -410,11 +410,11 @@
                    NoSuchAlgorithmException {
         try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
             SignatureInfo signatureInfo = findSignature(apk);
-            return ApkSigningBlockUtils.generateApkVerity(apkPath, bufferFactory, signatureInfo);
+            return VerityBuilder.generateApkVerity(apkPath, bufferFactory, signatureInfo);
         }
     }
 
-    static byte[] generateFsverityRootHash(String apkPath)
+    static byte[] generateApkVerityRootHash(String apkPath)
             throws IOException, SignatureNotFoundException, DigestException,
                    NoSuchAlgorithmException {
         try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
@@ -423,7 +423,7 @@
             if (vSigner.verityRootHash == null) {
                 return null;
             }
-            return ApkVerityBuilder.generateFsverityRootHash(
+            return VerityBuilder.generateApkVerityRootHash(
                     apk, ByteBuffer.wrap(vSigner.verityRootHash), signatureInfo);
         }
     }
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
index 758cd2b..1471870 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
@@ -534,11 +534,11 @@
                    NoSuchAlgorithmException {
         try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
             SignatureInfo signatureInfo = findSignature(apk);
-            return ApkSigningBlockUtils.generateApkVerity(apkPath, bufferFactory, signatureInfo);
+            return VerityBuilder.generateApkVerity(apkPath, bufferFactory, signatureInfo);
         }
     }
 
-    static byte[] generateFsverityRootHash(String apkPath)
+    static byte[] generateApkVerityRootHash(String apkPath)
             throws NoSuchAlgorithmException, DigestException, IOException,
                    SignatureNotFoundException {
         try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
@@ -547,7 +547,7 @@
             if (vSigner.verityRootHash == null) {
                 return null;
             }
-            return ApkVerityBuilder.generateFsverityRootHash(
+            return VerityBuilder.generateApkVerityRootHash(
                     apk, ByteBuffer.wrap(vSigner.verityRootHash), signatureInfo);
         }
     }
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index de9f55b..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) {
@@ -432,16 +428,16 @@
      *
      * @return FSverity root hash
      */
-    public static byte[] generateFsverityRootHash(String apkPath)
+    public static byte[] generateApkVerityRootHash(String apkPath)
             throws NoSuchAlgorithmException, DigestException, IOException {
         // first try v3
         try {
-            return ApkSignatureSchemeV3Verifier.generateFsverityRootHash(apkPath);
+            return ApkSignatureSchemeV3Verifier.generateApkVerityRootHash(apkPath);
         } catch (SignatureNotFoundException e) {
             // try older version
         }
         try {
-            return ApkSignatureSchemeV2Verifier.generateFsverityRootHash(apkPath);
+            return ApkSignatureSchemeV2Verifier.generateApkVerityRootHash(apkPath);
         } catch (SignatureNotFoundException e) {
             return null;
         }
diff --git a/core/java/android/util/apk/ApkSigningBlockUtils.java b/core/java/android/util/apk/ApkSigningBlockUtils.java
index e247c87..87af5364 100644
--- a/core/java/android/util/apk/ApkSigningBlockUtils.java
+++ b/core/java/android/util/apk/ApkSigningBlockUtils.java
@@ -332,7 +332,7 @@
         try {
             byte[] expectedRootHash = parseVerityDigestAndVerifySourceLength(expectedDigest,
                     apk.length(), signatureInfo);
-            ApkVerityBuilder.ApkVerityResult verity = ApkVerityBuilder.generateApkVerity(apk,
+            VerityBuilder.VerityResult verity = VerityBuilder.generateApkVerityTree(apk,
                     signatureInfo, new ByteBufferFactory() {
                         @Override
                         public ByteBuffer create(int capacity) {
@@ -348,26 +348,6 @@
     }
 
     /**
-     * Generates the fsverity header and hash tree to be used by kernel for the given apk. This
-     * method does not check whether the root hash exists in the Signing Block or not.
-     *
-     * <p>The output is stored in the {@link ByteBuffer} created by the given {@link
-     * ByteBufferFactory}.
-     *
-     * @return the root hash of the generated hash tree.
-     */
-    public static byte[] generateApkVerity(String apkPath, ByteBufferFactory bufferFactory,
-            SignatureInfo signatureInfo)
-            throws IOException, SignatureNotFoundException, SecurityException, DigestException,
-                   NoSuchAlgorithmException {
-        try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
-            ApkVerityBuilder.ApkVerityResult result = ApkVerityBuilder.generateApkVerity(apk,
-                    signatureInfo, bufferFactory);
-            return result.rootHash;
-        }
-    }
-
-    /**
      * Returns the ZIP End of Central Directory (EoCD) and its offset in the file.
      *
      * @throws IOException if an I/O error occurs while reading the file.
diff --git a/core/java/android/util/apk/ApkVerityBuilder.java b/core/java/android/util/apk/ApkVerityBuilder.java
deleted file mode 100644
index 2dd0117..0000000
--- a/core/java/android/util/apk/ApkVerityBuilder.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util.apk;
-
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.DigestException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-
-/**
- * ApkVerityBuilder builds the APK verity tree and the verity header, which will be used by the
- * kernel to verity the APK content on access.
- *
- * <p>Unlike a regular Merkle tree, APK verity tree does not cover the content fully. Due to
- * the existing APK format, it has to skip APK Signing Block and also has some special treatment for
- * the "Central Directory offset" field of ZIP End of Central Directory.
- *
- * @hide
- */
-abstract class ApkVerityBuilder {
-    private ApkVerityBuilder() {}
-
-    private static final int CHUNK_SIZE_BYTES = 4096;  // Typical Linux block size
-    private static final int DIGEST_SIZE_BYTES = 32;  // SHA-256 size
-    private static final int FSVERITY_HEADER_SIZE_BYTES = 64;
-    private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE = 4;
-    private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET = 16;
-    private static final String JCA_DIGEST_ALGORITHM = "SHA-256";
-    private static final byte[] DEFAULT_SALT = new byte[8];
-
-    static class ApkVerityResult {
-        public final ByteBuffer fsverityData;
-        public final byte[] rootHash;
-
-        ApkVerityResult(ByteBuffer fsverityData, byte[] rootHash) {
-            this.fsverityData = fsverityData;
-            this.rootHash = rootHash;
-        }
-    }
-
-    /**
-     * Generates fsverity metadata and the Merkle tree into the {@link ByteBuffer} created by the
-     * {@link ByteBufferFactory}. The bytes layout in the buffer will be used by the kernel and is
-     * ready to be appended to the target file to set up fsverity. For fsverity to work, this data
-     * must be placed at the next page boundary, and the caller must add additional padding in that
-     * case.
-     *
-     * @return ApkVerityResult containing the fsverity data and the root hash of the Merkle tree.
-     */
-    static ApkVerityResult generateApkVerity(RandomAccessFile apk,
-            SignatureInfo signatureInfo, ByteBufferFactory bufferFactory)
-            throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
-        long signingBlockSize =
-                signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
-        long dataSize = apk.length() - signingBlockSize;
-        int[] levelOffset = calculateVerityLevelOffset(dataSize);
-        int merkleTreeSize = levelOffset[levelOffset.length - 1];
-
-        ByteBuffer output = bufferFactory.create(
-                merkleTreeSize
-                + CHUNK_SIZE_BYTES);  // maximum size of fsverity metadata
-        output.order(ByteOrder.LITTLE_ENDIAN);
-
-        ByteBuffer tree = slice(output, 0, merkleTreeSize);
-        ByteBuffer header = slice(output, merkleTreeSize,
-                merkleTreeSize + FSVERITY_HEADER_SIZE_BYTES);
-        ByteBuffer extensions = slice(output, merkleTreeSize + FSVERITY_HEADER_SIZE_BYTES,
-                merkleTreeSize + CHUNK_SIZE_BYTES);
-        byte[] apkDigestBytes = new byte[DIGEST_SIZE_BYTES];
-        ByteBuffer apkDigest = ByteBuffer.wrap(apkDigestBytes);
-        apkDigest.order(ByteOrder.LITTLE_ENDIAN);
-
-        // NB: Buffer limit is set inside once finished.
-        calculateFsveritySignatureInternal(apk, signatureInfo, tree, apkDigest, header, extensions);
-
-        // Put the reverse offset to fs-verity header at the end.
-        output.position(merkleTreeSize + FSVERITY_HEADER_SIZE_BYTES + extensions.limit());
-        output.putInt(FSVERITY_HEADER_SIZE_BYTES + extensions.limit()
-                + 4);  // size of this integer right before EOF
-        output.flip();
-
-        return new ApkVerityResult(output, apkDigestBytes);
-    }
-
-    /**
-     * Calculates the fsverity root hash for integrity measurement.  This needs to be consistent to
-     * what kernel returns.
-     */
-    static byte[] generateFsverityRootHash(RandomAccessFile apk, ByteBuffer apkDigest,
-            SignatureInfo signatureInfo)
-            throws NoSuchAlgorithmException, DigestException, IOException {
-        ByteBuffer verityBlock = ByteBuffer.allocate(CHUNK_SIZE_BYTES)
-                .order(ByteOrder.LITTLE_ENDIAN);
-        ByteBuffer header = slice(verityBlock, 0, FSVERITY_HEADER_SIZE_BYTES);
-        ByteBuffer extensions = slice(verityBlock, FSVERITY_HEADER_SIZE_BYTES,
-                CHUNK_SIZE_BYTES - FSVERITY_HEADER_SIZE_BYTES);
-
-        calculateFsveritySignatureInternal(apk, signatureInfo, null, null, header, extensions);
-
-        MessageDigest md = MessageDigest.getInstance(JCA_DIGEST_ALGORITHM);
-        md.update(header);
-        md.update(extensions);
-        md.update(apkDigest);
-        return md.digest();
-    }
-
-    /**
-     * Internal method to generate various parts of FSVerity constructs, including the header,
-     * extensions, Merkle tree, and the tree's root hash.  The output buffer is flipped to the
-     * generated data size and is readey for consuming.
-     */
-    private static void calculateFsveritySignatureInternal(
-            RandomAccessFile apk, SignatureInfo signatureInfo, ByteBuffer treeOutput,
-            ByteBuffer rootHashOutput, ByteBuffer headerOutput, ByteBuffer extensionsOutput)
-            throws IOException, NoSuchAlgorithmException, DigestException {
-        assertSigningBlockAlignedAndHasFullPages(signatureInfo);
-        long signingBlockSize =
-                signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
-        long dataSize = apk.length() - signingBlockSize;
-        int[] levelOffset = calculateVerityLevelOffset(dataSize);
-
-        if (treeOutput != null) {
-            byte[] apkRootHash = generateApkVerityTree(apk, signatureInfo, DEFAULT_SALT,
-                    levelOffset, treeOutput);
-            if (rootHashOutput != null) {
-                rootHashOutput.put(apkRootHash);
-                rootHashOutput.flip();
-            }
-        }
-
-        if (headerOutput != null) {
-            headerOutput.order(ByteOrder.LITTLE_ENDIAN);
-            generateFsverityHeader(headerOutput, apk.length(), levelOffset.length - 1,
-                    DEFAULT_SALT);
-        }
-
-        if (extensionsOutput != null) {
-            extensionsOutput.order(ByteOrder.LITTLE_ENDIAN);
-            generateFsverityExtensions(extensionsOutput, signatureInfo.apkSigningBlockOffset,
-                    signingBlockSize, signatureInfo.eocdOffset);
-        }
-    }
-
-    /**
-     * A helper class to consume and digest data by block continuously, and write into a buffer.
-     */
-    private static class BufferedDigester implements DataDigester {
-        /** Amount of the data to digest in each cycle before writting out the digest. */
-        private static final int BUFFER_SIZE = CHUNK_SIZE_BYTES;
-
-        /**
-         * Amount of data the {@link MessageDigest} has consumed since the last reset. This must be
-         * always less than BUFFER_SIZE since {@link MessageDigest} is reset whenever it has
-         * consumed BUFFER_SIZE of data.
-         */
-        private int mBytesDigestedSinceReset;
-
-        /** The final output {@link ByteBuffer} to write the digest to sequentially. */
-        private final ByteBuffer mOutput;
-
-        private final MessageDigest mMd;
-        private final byte[] mDigestBuffer = new byte[DIGEST_SIZE_BYTES];
-        private final byte[] mSalt;
-
-        private BufferedDigester(byte[] salt, ByteBuffer output) throws NoSuchAlgorithmException {
-            mSalt = salt;
-            mOutput = output.slice();
-            mMd = MessageDigest.getInstance(JCA_DIGEST_ALGORITHM);
-            mMd.update(mSalt);
-            mBytesDigestedSinceReset = 0;
-        }
-
-        /**
-         * Consumes and digests data up to BUFFER_SIZE (may continue from the previous remaining),
-         * then writes the final digest to the output buffer.  Repeat until all data are consumed.
-         * If the last consumption is not enough for BUFFER_SIZE, the state will stay and future
-         * consumption will continuous from there.
-         */
-        @Override
-        public void consume(ByteBuffer buffer) throws DigestException {
-            int offset = buffer.position();
-            int remaining = buffer.remaining();
-            while (remaining > 0) {
-                int allowance = (int) Math.min(remaining, BUFFER_SIZE - mBytesDigestedSinceReset);
-                // Optimization: set the buffer limit to avoid allocating a new ByteBuffer object.
-                buffer.limit(buffer.position() + allowance);
-                mMd.update(buffer);
-                offset += allowance;
-                remaining -= allowance;
-                mBytesDigestedSinceReset += allowance;
-
-                if (mBytesDigestedSinceReset == BUFFER_SIZE) {
-                    mMd.digest(mDigestBuffer, 0, mDigestBuffer.length);
-                    mOutput.put(mDigestBuffer);
-                    // After digest, MessageDigest resets automatically, so no need to reset again.
-                    mMd.update(mSalt);
-                    mBytesDigestedSinceReset = 0;
-                }
-            }
-        }
-
-        public void assertEmptyBuffer() throws DigestException {
-            if (mBytesDigestedSinceReset != 0) {
-                throw new IllegalStateException("Buffer is not empty: " + mBytesDigestedSinceReset);
-            }
-        }
-
-        private void fillUpLastOutputChunk() {
-            int lastBlockSize = (int) (mOutput.position() % BUFFER_SIZE);
-            if (lastBlockSize == 0) {
-                return;
-            }
-            mOutput.put(ByteBuffer.allocate(BUFFER_SIZE - lastBlockSize));
-        }
-    }
-
-    /**
-     * Digest the source by chunk in the given range.  If the last chunk is not a full chunk,
-     * digest the remaining.
-     */
-    private static void consumeByChunk(DataDigester digester, DataSource source, int chunkSize)
-            throws IOException, DigestException {
-        long inputRemaining = source.size();
-        long inputOffset = 0;
-        while (inputRemaining > 0) {
-            int size = (int) Math.min(inputRemaining, chunkSize);
-            source.feedIntoDataDigester(digester, inputOffset, size);
-            inputOffset += size;
-            inputRemaining -= size;
-        }
-    }
-
-    // Rationale: 1) 1 MB should fit in memory space on all devices. 2) It is not too granular
-    // thus the syscall overhead is not too big.
-    private static final int MMAP_REGION_SIZE_BYTES = 1024 * 1024;
-
-    private static void generateApkVerityDigestAtLeafLevel(RandomAccessFile apk,
-            SignatureInfo signatureInfo, byte[] salt, ByteBuffer output)
-            throws IOException, NoSuchAlgorithmException, DigestException {
-        BufferedDigester digester = new BufferedDigester(salt, output);
-
-        // 1. Digest from the beginning of the file, until APK Signing Block is reached.
-        consumeByChunk(digester,
-                new MemoryMappedFileDataSource(apk.getFD(), 0, signatureInfo.apkSigningBlockOffset),
-                MMAP_REGION_SIZE_BYTES);
-
-        // 2. Skip APK Signing Block and continue digesting, until the Central Directory offset
-        // field in EoCD is reached.
-        long eocdCdOffsetFieldPosition =
-                signatureInfo.eocdOffset + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET;
-        consumeByChunk(digester,
-                new MemoryMappedFileDataSource(apk.getFD(), signatureInfo.centralDirOffset,
-                    eocdCdOffsetFieldPosition - signatureInfo.centralDirOffset),
-                MMAP_REGION_SIZE_BYTES);
-
-        // 3. Consume offset of Signing Block as an alternative EoCD.
-        ByteBuffer alternativeCentralDirOffset = ByteBuffer.allocate(
-                ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE).order(ByteOrder.LITTLE_ENDIAN);
-        alternativeCentralDirOffset.putInt(Math.toIntExact(signatureInfo.apkSigningBlockOffset));
-        alternativeCentralDirOffset.flip();
-        digester.consume(alternativeCentralDirOffset);
-
-        // 4. Read from end of the Central Directory offset field in EoCD to the end of the file.
-        long offsetAfterEocdCdOffsetField =
-                eocdCdOffsetFieldPosition + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
-        consumeByChunk(digester,
-                new MemoryMappedFileDataSource(apk.getFD(), offsetAfterEocdCdOffsetField,
-                    apk.length() - offsetAfterEocdCdOffsetField),
-                MMAP_REGION_SIZE_BYTES);
-
-        // 5. Pad 0s up to the nearest 4096-byte block before hashing.
-        int lastIncompleteChunkSize = (int) (apk.length() % CHUNK_SIZE_BYTES);
-        if (lastIncompleteChunkSize != 0) {
-            digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
-        }
-        digester.assertEmptyBuffer();
-
-        // 6. Fill up the rest of buffer with 0s.
-        digester.fillUpLastOutputChunk();
-    }
-
-    private static byte[] generateApkVerityTree(RandomAccessFile apk, SignatureInfo signatureInfo,
-            byte[] salt, int[] levelOffset, ByteBuffer output)
-            throws IOException, NoSuchAlgorithmException, DigestException {
-        // 1. Digest the apk to generate the leaf level hashes.
-        generateApkVerityDigestAtLeafLevel(apk, signatureInfo, salt, slice(output,
-                    levelOffset[levelOffset.length - 2], levelOffset[levelOffset.length - 1]));
-
-        // 2. Digest the lower level hashes bottom up.
-        for (int level = levelOffset.length - 3; level >= 0; level--) {
-            ByteBuffer inputBuffer = slice(output, levelOffset[level + 1], levelOffset[level + 2]);
-            ByteBuffer outputBuffer = slice(output, levelOffset[level], levelOffset[level + 1]);
-
-            DataSource source = new ByteBufferDataSource(inputBuffer);
-            BufferedDigester digester = new BufferedDigester(salt, outputBuffer);
-            consumeByChunk(digester, source, CHUNK_SIZE_BYTES);
-            digester.assertEmptyBuffer();
-            digester.fillUpLastOutputChunk();
-        }
-
-        // 3. Digest the first block (i.e. first level) to generate the root hash.
-        byte[] rootHash = new byte[DIGEST_SIZE_BYTES];
-        BufferedDigester digester = new BufferedDigester(salt, ByteBuffer.wrap(rootHash));
-        digester.consume(slice(output, 0, CHUNK_SIZE_BYTES));
-        digester.assertEmptyBuffer();
-        return rootHash;
-    }
-
-    private static ByteBuffer generateFsverityHeader(ByteBuffer buffer, long fileSize, int depth,
-            byte[] salt) {
-        if (salt.length != 8) {
-            throw new IllegalArgumentException("salt is not 8 bytes long");
-        }
-
-        // TODO(b/30972906): update the reference when there is a better one in public.
-        buffer.put("TrueBrew".getBytes());  // magic
-
-        buffer.put((byte) 1);               // major version
-        buffer.put((byte) 0);               // minor version
-        buffer.put((byte) 12);              // log2(block-size): log2(4096)
-        buffer.put((byte) 7);               // log2(leaves-per-node): log2(4096 / 32)
-
-        buffer.putShort((short) 1);         // meta algorithm, SHA256 == 1
-        buffer.putShort((short) 1);         // data algorithm, SHA256 == 1
-
-        buffer.putInt(0);                   // flags
-        buffer.putInt(0);                   // reserved
-
-        buffer.putLong(fileSize);           // original file size
-
-        buffer.put((byte) 2);               // authenticated extension count
-        buffer.put((byte) 0);               // unauthenticated extension count
-        buffer.put(salt);                   // salt (8 bytes)
-        skip(buffer, 22);                   // reserved
-
-        buffer.flip();
-        return buffer;
-    }
-
-    private static ByteBuffer generateFsverityExtensions(ByteBuffer buffer, long signingBlockOffset,
-            long signingBlockSize, long eocdOffset) {
-        // Snapshot of the FSVerity structs (subject to change once upstreamed).
-        //
-        // struct fsverity_extension_elide {
-        //   __le64 offset;
-        //   __le64 length;
-        // }
-        //
-        // struct fsverity_extension_patch {
-        //   __le64 offset;
-        //   u8 databytes[];
-        // };
-
-        final int kSizeOfFsverityExtensionHeader = 8;
-        final int kExtensionSizeAlignment = 8;
-
-        {
-            // struct fsverity_extension #1
-            final int kSizeOfFsverityElidedExtension = 16;
-
-            // First field is total size of extension, padded to 64-bit alignment
-            buffer.putInt(kSizeOfFsverityExtensionHeader + kSizeOfFsverityElidedExtension);
-            buffer.putShort((short) 1);  // ID of elide extension
-            skip(buffer, 2);             // reserved
-
-            // struct fsverity_extension_elide
-            buffer.putLong(signingBlockOffset);
-            buffer.putLong(signingBlockSize);
-        }
-
-        {
-            // struct fsverity_extension #2
-            final int kTotalSize = kSizeOfFsverityExtensionHeader
-                    + 8 // offset size
-                    + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
-
-            buffer.putInt(kTotalSize);   // Total size of extension, padded to 64-bit alignment
-            buffer.putShort((short) 2);  // ID of patch extension
-            skip(buffer, 2);             // reserved
-
-            // struct fsverity_extension_patch
-            buffer.putLong(eocdOffset + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);  // offset
-            buffer.putInt(Math.toIntExact(signingBlockOffset));  // databytes
-
-            // The extension needs to be 0-padded at the end, since the length may not be multiple
-            // of 8.
-            int kPadding = kExtensionSizeAlignment - kTotalSize % kExtensionSizeAlignment;
-            if (kPadding == kExtensionSizeAlignment) {
-                kPadding = 0;
-            }
-            skip(buffer, kPadding);      // padding
-        }
-
-        buffer.flip();
-        return buffer;
-    }
-
-    /**
-     * Returns an array of summed area table of level size in the verity tree.  In other words, the
-     * returned array is offset of each level in the verity tree file format, plus an additional
-     * offset of the next non-existing level (i.e. end of the last level + 1).  Thus the array size
-     * is level + 1.  Thus, the returned array is guarantee to have at least 2 elements.
-     */
-    private static int[] calculateVerityLevelOffset(long fileSize) {
-        ArrayList<Long> levelSize = new ArrayList<>();
-        while (true) {
-            long levelDigestSize = divideRoundup(fileSize, CHUNK_SIZE_BYTES) * DIGEST_SIZE_BYTES;
-            long chunksSize = CHUNK_SIZE_BYTES * divideRoundup(levelDigestSize, CHUNK_SIZE_BYTES);
-            levelSize.add(chunksSize);
-            if (levelDigestSize <= CHUNK_SIZE_BYTES) {
-                break;
-            }
-            fileSize = levelDigestSize;
-        }
-
-        // Reverse and convert to summed area table.
-        int[] levelOffset = new int[levelSize.size() + 1];
-        levelOffset[0] = 0;
-        for (int i = 0; i < levelSize.size(); i++) {
-            // We don't support verity tree if it is larger then Integer.MAX_VALUE.
-            levelOffset[i + 1] = levelOffset[i]
-                    + Math.toIntExact(levelSize.get(levelSize.size() - i - 1));
-        }
-        return levelOffset;
-    }
-
-    private static void assertSigningBlockAlignedAndHasFullPages(SignatureInfo signatureInfo) {
-        if (signatureInfo.apkSigningBlockOffset % CHUNK_SIZE_BYTES != 0) {
-            throw new IllegalArgumentException(
-                    "APK Signing Block does not start at the page  boundary: "
-                    + signatureInfo.apkSigningBlockOffset);
-        }
-
-        if ((signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset)
-                % CHUNK_SIZE_BYTES != 0) {
-            throw new IllegalArgumentException(
-                    "Size of APK Signing Block is not a multiple of 4096: "
-                    + (signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset));
-        }
-    }
-
-    /** Returns a slice of the buffer which shares content with the provided buffer. */
-    private static ByteBuffer slice(ByteBuffer buffer, int begin, int end) {
-        ByteBuffer b = buffer.duplicate();
-        b.position(0);  // to ensure position <= limit invariant.
-        b.limit(end);
-        b.position(begin);
-        return b.slice();
-    }
-
-    /** Skip the {@code ByteBuffer} position by {@code bytes}. */
-    private static void skip(ByteBuffer buffer, int bytes) {
-        buffer.position(buffer.position() + bytes);
-    }
-
-    /** Divides a number and round up to the closest integer. */
-    private static long divideRoundup(long dividend, long divisor) {
-        return (dividend + divisor - 1) / divisor;
-    }
-}
diff --git a/core/java/android/util/apk/VerityBuilder.java b/core/java/android/util/apk/VerityBuilder.java
new file mode 100644
index 0000000..443bbd8
--- /dev/null
+++ b/core/java/android/util/apk/VerityBuilder.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util.apk;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+
+/**
+ * VerityBuilder builds the verity Merkle tree and other metadata.  The generated tree format can
+ * be stored on disk for fs-verity setup and used by kernel.  The builder support standard
+ * fs-verity, and Android specific apk-verity that requires additional kernel patches.
+ *
+ * <p>Unlike a regular Merkle tree of fs-verity, the apk-verity tree does not cover the file content
+ * fully, and has to skip APK Signing Block with some special treatment for the "Central Directory
+ * offset" field of ZIP End of Central Directory.
+ *
+ * @hide
+ */
+public abstract class VerityBuilder {
+    private VerityBuilder() {}
+
+    private static final int CHUNK_SIZE_BYTES = 4096;  // Typical Linux block size
+    private static final int DIGEST_SIZE_BYTES = 32;  // SHA-256 size
+    private static final int FSVERITY_HEADER_SIZE_BYTES = 64;
+    private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE = 4;
+    private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET = 16;
+    private static final String JCA_DIGEST_ALGORITHM = "SHA-256";
+    private static final byte[] DEFAULT_SALT = new byte[8];
+
+    /** Result generated by the builder. */
+    public static class VerityResult {
+        /** Raw fs-verity metadata and Merkle tree ready to be deployed on disk. */
+        public final ByteBuffer verityData;
+
+        /** Size of the Merkle tree in {@code verityData}. */
+        public final int merkleTreeSize;
+
+        /** Root hash of the Merkle tree. */
+        public final byte[] rootHash;
+
+        private VerityResult(ByteBuffer verityData, int merkleTreeSize, byte[] rootHash) {
+            this.verityData = verityData;
+            this.merkleTreeSize = merkleTreeSize;
+            this.rootHash = rootHash;
+        }
+    }
+
+    /**
+     * Generates the 4k, SHA-256 based Merkle tree for the given APK and stores in the {@link
+     * ByteBuffer} created by the {@link ByteBufferFactory}.  The output is suitable to be used as
+     * the on-disk format for fs-verity to use.
+     *
+     * @return VerityResult containing a buffer with the generated Merkle tree stored at the
+     *         front, the tree size, and the calculated root hash.
+     */
+    @NonNull
+    public static VerityResult generateFsVerityTree(@NonNull RandomAccessFile apk,
+            @NonNull ByteBufferFactory bufferFactory)
+            throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
+        return generateVerityTreeInternal(apk, bufferFactory, null /* signatureInfo */,
+                false /* skipSigningBlock */);
+    }
+
+    /**
+     * Generates the 4k, SHA-256 based Merkle tree for the given APK and stores in the {@link
+     * ByteBuffer} created by the {@link ByteBufferFactory}.  The Merkle tree does not cover Signing
+     * Block specificed in {@code signatureInfo}.  The output is suitable to be used as the on-disk
+     * format for fs-verity to use (with elide and patch extensions).
+     *
+     * @return VerityResult containing a buffer with the generated Merkle tree stored at the
+     *         front, the tree size, and the calculated root hash.
+     */
+    @NonNull
+    public static VerityResult generateApkVerityTree(@NonNull RandomAccessFile apk,
+            @Nullable SignatureInfo signatureInfo, @NonNull ByteBufferFactory bufferFactory)
+            throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
+        return generateVerityTreeInternal(apk, bufferFactory, signatureInfo,
+                true /* skipSigningBlock */);
+    }
+
+    @NonNull
+    private static VerityResult generateVerityTreeInternal(@NonNull RandomAccessFile apk,
+            @NonNull ByteBufferFactory bufferFactory, @Nullable SignatureInfo signatureInfo,
+            boolean skipSigningBlock)
+            throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
+        long dataSize = apk.length();
+        if (skipSigningBlock) {
+            long signingBlockSize =
+                    signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
+            dataSize -= signingBlockSize;
+        }
+        int[] levelOffset = calculateVerityLevelOffset(dataSize);
+        int merkleTreeSize = levelOffset[levelOffset.length - 1];
+
+        ByteBuffer output = bufferFactory.create(
+                merkleTreeSize
+                + CHUNK_SIZE_BYTES);  // maximum size of apk-verity metadata
+        output.order(ByteOrder.LITTLE_ENDIAN);
+        ByteBuffer tree = slice(output, 0, merkleTreeSize);
+        // Only use default salt in legacy case.
+        byte[] salt = skipSigningBlock ? DEFAULT_SALT : null;
+        byte[] apkRootHash = generateVerityTreeInternal(apk, signatureInfo, salt, levelOffset,
+                tree, skipSigningBlock);
+        return new VerityResult(output, merkleTreeSize, apkRootHash);
+    }
+
+    static void generateApkVerityFooter(@NonNull RandomAccessFile apk,
+            @NonNull SignatureInfo signatureInfo, @NonNull ByteBuffer footerOutput)
+            throws IOException {
+        footerOutput.order(ByteOrder.LITTLE_ENDIAN);
+        generateApkVerityHeader(footerOutput, apk.length(), DEFAULT_SALT);
+        long signingBlockSize =
+                signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
+        generateApkVerityExtensions(footerOutput, signatureInfo.apkSigningBlockOffset,
+                signingBlockSize, signatureInfo.eocdOffset);
+    }
+
+    /**
+     * Calculates the apk-verity root hash for integrity measurement.  This needs to be consistent
+     * to what kernel returns.
+     */
+    @NonNull
+    static byte[] generateApkVerityRootHash(@NonNull RandomAccessFile apk,
+            @NonNull ByteBuffer apkDigest, @NonNull SignatureInfo signatureInfo)
+            throws NoSuchAlgorithmException, DigestException, IOException {
+        assertSigningBlockAlignedAndHasFullPages(signatureInfo);
+
+        ByteBuffer footer = ByteBuffer.allocate(CHUNK_SIZE_BYTES).order(ByteOrder.LITTLE_ENDIAN);
+        generateApkVerityFooter(apk, signatureInfo, footer);
+        footer.flip();
+
+        MessageDigest md = MessageDigest.getInstance(JCA_DIGEST_ALGORITHM);
+        md.update(footer);
+        md.update(apkDigest);
+        return md.digest();
+    }
+
+    /**
+     * Generates the apk-verity header and hash tree to be used by kernel for the given apk. This
+     * method does not check whether the root hash exists in the Signing Block or not.
+     *
+     * <p>The output is stored in the {@link ByteBuffer} created by the given {@link
+     * ByteBufferFactory}.
+     *
+     * @return the root hash of the generated hash tree.
+     */
+    @NonNull
+    static byte[] generateApkVerity(@NonNull String apkPath,
+            @NonNull ByteBufferFactory bufferFactory, @NonNull SignatureInfo signatureInfo)
+            throws IOException, SignatureNotFoundException, SecurityException, DigestException,
+                   NoSuchAlgorithmException {
+        try (RandomAccessFile apk = new RandomAccessFile(apkPath, "r")) {
+            VerityResult result = generateVerityTreeInternal(apk, bufferFactory, signatureInfo,
+                    true /* skipSigningBlock */);
+            ByteBuffer footer = slice(result.verityData, result.merkleTreeSize,
+                    result.verityData.limit());
+            generateApkVerityFooter(apk, signatureInfo, footer);
+            // Put the reverse offset to apk-verity header at the end.
+            footer.putInt(footer.position() + 4);
+            result.verityData.limit(result.merkleTreeSize + footer.position());
+            return result.rootHash;
+        }
+    }
+
+    /**
+     * A helper class to consume and digest data by block continuously, and write into a buffer.
+     */
+    private static class BufferedDigester implements DataDigester {
+        /** Amount of the data to digest in each cycle before writting out the digest. */
+        private static final int BUFFER_SIZE = CHUNK_SIZE_BYTES;
+
+        /**
+         * Amount of data the {@link MessageDigest} has consumed since the last reset. This must be
+         * always less than BUFFER_SIZE since {@link MessageDigest} is reset whenever it has
+         * consumed BUFFER_SIZE of data.
+         */
+        private int mBytesDigestedSinceReset;
+
+        /** The final output {@link ByteBuffer} to write the digest to sequentially. */
+        private final ByteBuffer mOutput;
+
+        private final MessageDigest mMd;
+        private final byte[] mDigestBuffer = new byte[DIGEST_SIZE_BYTES];
+        private final byte[] mSalt;
+
+        private BufferedDigester(@Nullable byte[] salt, @NonNull ByteBuffer output)
+                throws NoSuchAlgorithmException {
+            mSalt = salt;
+            mOutput = output.slice();
+            mMd = MessageDigest.getInstance(JCA_DIGEST_ALGORITHM);
+            if (mSalt != null) {
+                mMd.update(mSalt);
+            }
+            mBytesDigestedSinceReset = 0;
+        }
+
+        /**
+         * Consumes and digests data up to BUFFER_SIZE (may continue from the previous remaining),
+         * then writes the final digest to the output buffer.  Repeat until all data are consumed.
+         * If the last consumption is not enough for BUFFER_SIZE, the state will stay and future
+         * consumption will continuous from there.
+         */
+        @Override
+        public void consume(ByteBuffer buffer) throws DigestException {
+            int offset = buffer.position();
+            int remaining = buffer.remaining();
+            while (remaining > 0) {
+                int allowance = (int) Math.min(remaining, BUFFER_SIZE - mBytesDigestedSinceReset);
+                // Optimization: set the buffer limit to avoid allocating a new ByteBuffer object.
+                buffer.limit(buffer.position() + allowance);
+                mMd.update(buffer);
+                offset += allowance;
+                remaining -= allowance;
+                mBytesDigestedSinceReset += allowance;
+
+                if (mBytesDigestedSinceReset == BUFFER_SIZE) {
+                    mMd.digest(mDigestBuffer, 0, mDigestBuffer.length);
+                    mOutput.put(mDigestBuffer);
+                    // After digest, MessageDigest resets automatically, so no need to reset again.
+                    if (mSalt != null) {
+                        mMd.update(mSalt);
+                    }
+                    mBytesDigestedSinceReset = 0;
+                }
+            }
+        }
+
+        public void assertEmptyBuffer() throws DigestException {
+            if (mBytesDigestedSinceReset != 0) {
+                throw new IllegalStateException("Buffer is not empty: " + mBytesDigestedSinceReset);
+            }
+        }
+
+        private void fillUpLastOutputChunk() {
+            int lastBlockSize = (int) (mOutput.position() % BUFFER_SIZE);
+            if (lastBlockSize == 0) {
+                return;
+            }
+            mOutput.put(ByteBuffer.allocate(BUFFER_SIZE - lastBlockSize));
+        }
+    }
+
+    /**
+     * Digest the source by chunk in the given range.  If the last chunk is not a full chunk,
+     * digest the remaining.
+     */
+    private static void consumeByChunk(DataDigester digester, DataSource source, int chunkSize)
+            throws IOException, DigestException {
+        long inputRemaining = source.size();
+        long inputOffset = 0;
+        while (inputRemaining > 0) {
+            int size = (int) Math.min(inputRemaining, chunkSize);
+            source.feedIntoDataDigester(digester, inputOffset, size);
+            inputOffset += size;
+            inputRemaining -= size;
+        }
+    }
+
+    // Rationale: 1) 1 MB should fit in memory space on all devices. 2) It is not too granular
+    // thus the syscall overhead is not too big.
+    private static final int MMAP_REGION_SIZE_BYTES = 1024 * 1024;
+
+    private static void generateFsVerityDigestAtLeafLevel(RandomAccessFile file, ByteBuffer output)
+            throws IOException, NoSuchAlgorithmException, DigestException {
+        BufferedDigester digester = new BufferedDigester(null /* salt */, output);
+
+        // 1. Digest the whole file by chunks.
+        consumeByChunk(digester,
+                new MemoryMappedFileDataSource(file.getFD(), 0, file.length()),
+                MMAP_REGION_SIZE_BYTES);
+
+        // 2. Pad 0s up to the nearest 4096-byte block before hashing.
+        int lastIncompleteChunkSize = (int) (file.length() % CHUNK_SIZE_BYTES);
+        if (lastIncompleteChunkSize != 0) {
+            digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
+        }
+        digester.assertEmptyBuffer();
+
+        // 3. Fill up the rest of buffer with 0s.
+        digester.fillUpLastOutputChunk();
+    }
+
+    private static void generateApkVerityDigestAtLeafLevel(RandomAccessFile apk,
+            SignatureInfo signatureInfo, byte[] salt, ByteBuffer output)
+            throws IOException, NoSuchAlgorithmException, DigestException {
+        BufferedDigester digester = new BufferedDigester(salt, output);
+
+        // 1. Digest from the beginning of the file, until APK Signing Block is reached.
+        consumeByChunk(digester,
+                new MemoryMappedFileDataSource(apk.getFD(), 0, signatureInfo.apkSigningBlockOffset),
+                MMAP_REGION_SIZE_BYTES);
+
+        // 2. Skip APK Signing Block and continue digesting, until the Central Directory offset
+        // field in EoCD is reached.
+        long eocdCdOffsetFieldPosition =
+                signatureInfo.eocdOffset + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET;
+        consumeByChunk(digester,
+                new MemoryMappedFileDataSource(apk.getFD(), signatureInfo.centralDirOffset,
+                    eocdCdOffsetFieldPosition - signatureInfo.centralDirOffset),
+                MMAP_REGION_SIZE_BYTES);
+
+        // 3. Consume offset of Signing Block as an alternative EoCD.
+        ByteBuffer alternativeCentralDirOffset = ByteBuffer.allocate(
+                ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE).order(ByteOrder.LITTLE_ENDIAN);
+        alternativeCentralDirOffset.putInt(Math.toIntExact(signatureInfo.apkSigningBlockOffset));
+        alternativeCentralDirOffset.flip();
+        digester.consume(alternativeCentralDirOffset);
+
+        // 4. Read from end of the Central Directory offset field in EoCD to the end of the file.
+        long offsetAfterEocdCdOffsetField =
+                eocdCdOffsetFieldPosition + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
+        consumeByChunk(digester,
+                new MemoryMappedFileDataSource(apk.getFD(), offsetAfterEocdCdOffsetField,
+                    apk.length() - offsetAfterEocdCdOffsetField),
+                MMAP_REGION_SIZE_BYTES);
+
+        // 5. Pad 0s up to the nearest 4096-byte block before hashing.
+        int lastIncompleteChunkSize = (int) (apk.length() % CHUNK_SIZE_BYTES);
+        if (lastIncompleteChunkSize != 0) {
+            digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
+        }
+        digester.assertEmptyBuffer();
+
+        // 6. Fill up the rest of buffer with 0s.
+        digester.fillUpLastOutputChunk();
+    }
+
+    @NonNull
+    private static byte[] generateVerityTreeInternal(@NonNull RandomAccessFile apk,
+            @Nullable SignatureInfo signatureInfo, @Nullable byte[] salt,
+            @NonNull int[] levelOffset, @NonNull ByteBuffer output, boolean skipSigningBlock)
+            throws IOException, NoSuchAlgorithmException, DigestException {
+        // 1. Digest the apk to generate the leaf level hashes.
+        if (skipSigningBlock) {
+            assertSigningBlockAlignedAndHasFullPages(signatureInfo);
+            generateApkVerityDigestAtLeafLevel(apk, signatureInfo, salt, slice(output,
+                        levelOffset[levelOffset.length - 2], levelOffset[levelOffset.length - 1]));
+        } else {
+            generateFsVerityDigestAtLeafLevel(apk, slice(output,
+                        levelOffset[levelOffset.length - 2], levelOffset[levelOffset.length - 1]));
+        }
+
+        // 2. Digest the lower level hashes bottom up.
+        for (int level = levelOffset.length - 3; level >= 0; level--) {
+            ByteBuffer inputBuffer = slice(output, levelOffset[level + 1], levelOffset[level + 2]);
+            ByteBuffer outputBuffer = slice(output, levelOffset[level], levelOffset[level + 1]);
+
+            DataSource source = new ByteBufferDataSource(inputBuffer);
+            BufferedDigester digester = new BufferedDigester(salt, outputBuffer);
+            consumeByChunk(digester, source, CHUNK_SIZE_BYTES);
+            digester.assertEmptyBuffer();
+            digester.fillUpLastOutputChunk();
+        }
+
+        // 3. Digest the first block (i.e. first level) to generate the root hash.
+        byte[] rootHash = new byte[DIGEST_SIZE_BYTES];
+        BufferedDigester digester = new BufferedDigester(salt, ByteBuffer.wrap(rootHash));
+        digester.consume(slice(output, 0, CHUNK_SIZE_BYTES));
+        digester.assertEmptyBuffer();
+        return rootHash;
+    }
+
+    private static ByteBuffer generateApkVerityHeader(ByteBuffer buffer, long fileSize,
+            byte[] salt) {
+        if (salt.length != 8) {
+            throw new IllegalArgumentException("salt is not 8 bytes long");
+        }
+
+        // TODO(b/30972906): update the reference when there is a better one in public.
+        buffer.put("TrueBrew".getBytes());  // magic
+
+        buffer.put((byte) 1);               // major version
+        buffer.put((byte) 0);               // minor version
+        buffer.put((byte) 12);              // log2(block-size): log2(4096)
+        buffer.put((byte) 7);               // log2(leaves-per-node): log2(4096 / 32)
+
+        buffer.putShort((short) 1);         // meta algorithm, SHA256 == 1
+        buffer.putShort((short) 1);         // data algorithm, SHA256 == 1
+
+        buffer.putInt(0);                   // flags
+        buffer.putInt(0);                   // reserved
+
+        buffer.putLong(fileSize);           // original file size
+
+        buffer.put((byte) 2);               // authenticated extension count
+        buffer.put((byte) 0);               // unauthenticated extension count
+        buffer.put(salt);                   // salt (8 bytes)
+        skip(buffer, 22);                   // reserved
+
+        return buffer;
+    }
+
+    private static ByteBuffer generateApkVerityExtensions(ByteBuffer buffer,
+            long signingBlockOffset, long signingBlockSize, long eocdOffset) {
+        // Snapshot of the experimental fs-verity structs (different from upstream).
+        //
+        // struct fsverity_extension_elide {
+        //   __le64 offset;
+        //   __le64 length;
+        // }
+        //
+        // struct fsverity_extension_patch {
+        //   __le64 offset;
+        //   u8 databytes[];
+        // };
+
+        final int kSizeOfFsverityExtensionHeader = 8;
+        final int kExtensionSizeAlignment = 8;
+
+        {
+            // struct fsverity_extension #1
+            final int kSizeOfFsverityElidedExtension = 16;
+
+            // First field is total size of extension, padded to 64-bit alignment
+            buffer.putInt(kSizeOfFsverityExtensionHeader + kSizeOfFsverityElidedExtension);
+            buffer.putShort((short) 1);  // ID of elide extension
+            skip(buffer, 2);             // reserved
+
+            // struct fsverity_extension_elide
+            buffer.putLong(signingBlockOffset);
+            buffer.putLong(signingBlockSize);
+        }
+
+        {
+            // struct fsverity_extension #2
+            final int kTotalSize = kSizeOfFsverityExtensionHeader
+                    + 8 // offset size
+                    + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
+
+            buffer.putInt(kTotalSize);   // Total size of extension, padded to 64-bit alignment
+            buffer.putShort((short) 2);  // ID of patch extension
+            skip(buffer, 2);             // reserved
+
+            // struct fsverity_extension_patch
+            buffer.putLong(eocdOffset + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);  // offset
+            buffer.putInt(Math.toIntExact(signingBlockOffset));  // databytes
+
+            // The extension needs to be 0-padded at the end, since the length may not be multiple
+            // of 8.
+            int kPadding = kExtensionSizeAlignment - kTotalSize % kExtensionSizeAlignment;
+            if (kPadding == kExtensionSizeAlignment) {
+                kPadding = 0;
+            }
+            skip(buffer, kPadding);      // padding
+        }
+
+        return buffer;
+    }
+
+    /**
+     * Returns an array of summed area table of level size in the verity tree.  In other words, the
+     * returned array is offset of each level in the verity tree file format, plus an additional
+     * offset of the next non-existing level (i.e. end of the last level + 1).  Thus the array size
+     * is level + 1.  Thus, the returned array is guarantee to have at least 2 elements.
+     */
+    private static int[] calculateVerityLevelOffset(long fileSize) {
+        ArrayList<Long> levelSize = new ArrayList<>();
+        while (true) {
+            long levelDigestSize = divideRoundup(fileSize, CHUNK_SIZE_BYTES) * DIGEST_SIZE_BYTES;
+            long chunksSize = CHUNK_SIZE_BYTES * divideRoundup(levelDigestSize, CHUNK_SIZE_BYTES);
+            levelSize.add(chunksSize);
+            if (levelDigestSize <= CHUNK_SIZE_BYTES) {
+                break;
+            }
+            fileSize = levelDigestSize;
+        }
+
+        // Reverse and convert to summed area table.
+        int[] levelOffset = new int[levelSize.size() + 1];
+        levelOffset[0] = 0;
+        for (int i = 0; i < levelSize.size(); i++) {
+            // We don't support verity tree if it is larger then Integer.MAX_VALUE.
+            levelOffset[i + 1] = levelOffset[i]
+                    + Math.toIntExact(levelSize.get(levelSize.size() - i - 1));
+        }
+        return levelOffset;
+    }
+
+    private static void assertSigningBlockAlignedAndHasFullPages(
+            @NonNull SignatureInfo signatureInfo) {
+        if (signatureInfo.apkSigningBlockOffset % CHUNK_SIZE_BYTES != 0) {
+            throw new IllegalArgumentException(
+                    "APK Signing Block does not start at the page boundary: "
+                    + signatureInfo.apkSigningBlockOffset);
+        }
+
+        if ((signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset)
+                % CHUNK_SIZE_BYTES != 0) {
+            throw new IllegalArgumentException(
+                    "Size of APK Signing Block is not a multiple of 4096: "
+                    + (signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset));
+        }
+    }
+
+    /** Returns a slice of the buffer which shares content with the provided buffer. */
+    private static ByteBuffer slice(ByteBuffer buffer, int begin, int end) {
+        ByteBuffer b = buffer.duplicate();
+        b.position(0);  // to ensure position <= limit invariant.
+        b.limit(end);
+        b.position(begin);
+        return b.slice();
+    }
+
+    /** Skip the {@code ByteBuffer} position by {@code bytes}. */
+    private static void skip(ByteBuffer buffer, int bytes) {
+        buffer.position(buffer.position() + bytes);
+    }
+
+    /** Divides a number and round up to the closest integer. */
+    private static long divideRoundup(long dividend, long divisor) {
+        return (dividend + divisor - 1) / divisor;
+    }
+}
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..f428c79 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,152 @@
     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(
+            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 +258,85 @@
      *                   {@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)
+    @Deprecated
     public DisplayCutout(Rect safeInsets, List<Rect> boundingRects) {
-        this(safeInsets != null ? new Rect(safeInsets) : ZERO_RECT,
-                boundingRectsToRegion(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;
+        }
+        for (Rect bound : boundingRects) {
+            // There will be at most one non-functional area per short edge of the device, and 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 +349,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 +380,89 @@
     }
 
     /**
-     * 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.
      */
     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 +472,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 +480,7 @@
     @Override
     public String toString() {
         return "DisplayCutout{insets=" + mSafeInsets
-                + " boundingRect=" + mBounds.getBounds()
+                + " boundingRect={" + mBounds + "}"
                 + "}";
     }
 
@@ -265,7 +490,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 +504,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 +526,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 +545,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 +559,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 +573,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 +659,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 +677,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 +707,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 +749,7 @@
             } else {
                 out.writeInt(1);
                 out.writeTypedObject(cutout.mSafeInsets, flags);
-                out.writeTypedObject(cutout.mBounds, flags);
+                out.writeTypedArray(cutout.mBounds.getRects(), flags);
             }
         }
 
@@ -561,7 +790,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/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 4b946d7..667fab5 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -19,6 +19,7 @@
 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;
@@ -35,7 +36,7 @@
  *
  * @hide
  */
-public final class DisplayListCanvas extends RecordingCanvas {
+public final class DisplayListCanvas 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;
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index bfe1e95..3e559d9 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -17,8 +17,6 @@
 package android.view;
 
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IShortcutService;
 
@@ -71,8 +69,7 @@
     boolean stopViewServer();            // Transaction #2
     boolean isViewServerRunning();       // Transaction #3
 
-    IWindowSession openSession(in IWindowSessionCallback callback, in IInputMethodClient client,
-            in IInputContext inputContext);
+    IWindowSession openSession(in IWindowSessionCallback callback);
 
     void getInitialDisplaySize(int displayId, out Point size);
     void getBaseDisplaySize(int displayId, out Point size);
@@ -90,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,
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/NativeVectorDrawableAnimator.java b/core/java/android/view/NativeVectorDrawableAnimator.java
new file mode 100644
index 0000000..b0556a3
--- /dev/null
+++ b/core/java/android/view/NativeVectorDrawableAnimator.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+/**
+ * Exists just to allow for android.graphics & android.view package separation
+ *
+ * TODO: Get off of this coupling more cleanly somehow
+ *
+ * @hide
+ */
+public interface NativeVectorDrawableAnimator {
+    /** @hide */
+    long getAnimatorNativePtr();
+}
diff --git a/core/java/android/view/RecordingCanvas.java b/core/java/android/view/RecordingCanvas.java
deleted file mode 100644
index 3364483..0000000
--- a/core/java/android/view/RecordingCanvas.java
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.ColorInt;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.Size;
-import android.graphics.BaseCanvas;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.NinePatch;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Picture;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.TemporaryBuffer;
-import android.text.GraphicsOperations;
-import android.text.MeasuredParagraph;
-import android.text.PrecomputedText;
-import android.text.SpannableString;
-import android.text.SpannedString;
-import android.text.TextUtils;
-
-import dalvik.annotation.optimization.FastNative;
-
-/**
- * This class is a base class for canvases that defer drawing operations, so all
- * the draw operations can be marked @FastNative. It contains a re-implementation of
- * all the methods in {@link BaseCanvas}.
- *
- * @hide
- */
-public class RecordingCanvas extends Canvas {
-
-    public RecordingCanvas(long nativeCanvas) {
-        super(nativeCanvas);
-    }
-
-    @Override
-    public final void drawArc(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle, boolean useCenter, @NonNull Paint paint) {
-        nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
-                useCenter, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle,
-            boolean useCenter, @NonNull Paint paint) {
-        drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
-                paint);
-    }
-
-    @Override
-    public final void drawARGB(int a, int r, int g, int b) {
-        drawColor(Color.argb(a, r, g, b));
-    }
-
-    @Override
-    public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top,
-            @Nullable Paint paint) {
-        throwIfCannotDraw(bitmap);
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
-                paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
-                bitmap.mDensity);
-    }
-
-    @Override
-    public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix,
-            @Nullable Paint paint) {
-        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
-                paint != null ? paint.getNativeInstance() : 0);
-    }
-
-    @Override
-    public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
-            @Nullable Paint paint) {
-        if (dst == null) {
-            throw new NullPointerException();
-        }
-        throwIfCannotDraw(bitmap);
-        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
-
-        int left, top, right, bottom;
-        if (src == null) {
-            left = top = 0;
-            right = bitmap.getWidth();
-            bottom = bitmap.getHeight();
-        } else {
-            left = src.left;
-            right = src.right;
-            top = src.top;
-            bottom = src.bottom;
-        }
-
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
-                dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
-                bitmap.mDensity);
-    }
-
-    @Override
-    public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
-            @Nullable Paint paint) {
-        if (dst == null) {
-            throw new NullPointerException();
-        }
-        throwIfCannotDraw(bitmap);
-        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
-
-        float left, top, right, bottom;
-        if (src == null) {
-            left = top = 0;
-            right = bitmap.getWidth();
-            bottom = bitmap.getHeight();
-        } else {
-            left = src.left;
-            right = src.right;
-            top = src.top;
-            bottom = src.bottom;
-        }
-
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
-                dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
-                bitmap.mDensity);
-    }
-
-    /** @deprecated checkstyle */
-    @Override
-    @Deprecated
-    public final void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y,
-            int width, int height, boolean hasAlpha, @Nullable Paint paint) {
-        // check for valid input
-        if (width < 0) {
-            throw new IllegalArgumentException("width must be >= 0");
-        }
-        if (height < 0) {
-            throw new IllegalArgumentException("height must be >= 0");
-        }
-        if (Math.abs(stride) < width) {
-            throw new IllegalArgumentException("abs(stride) must be >= width");
-        }
-        int lastScanline = offset + (height - 1) * stride;
-        int length = colors.length;
-        if (offset < 0 || (offset + width > length) || lastScanline < 0
-                || (lastScanline + width > length)) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        // quick escape if there's nothing to draw
-        if (width == 0 || height == 0) {
-            return;
-        }
-        // punch down to native for the actual draw
-        nDrawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
-                paint != null ? paint.getNativeInstance() : 0);
-    }
-
-    /** @deprecated checkstyle */
-    @Override
-    @Deprecated
-    public final void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y,
-            int width, int height, boolean hasAlpha, @Nullable Paint paint) {
-        // call through to the common float version
-        drawBitmap(colors, offset, stride, (float) x, (float) y, width, height,
-                hasAlpha, paint);
-    }
-
-    @Override
-    public final void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight,
-            @NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset,
-            @Nullable Paint paint) {
-        if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        if (meshWidth == 0 || meshHeight == 0) {
-            return;
-        }
-        int count = (meshWidth + 1) * (meshHeight + 1);
-        // we mul by 2 since we need two floats per vertex
-        checkRange(verts.length, vertOffset, count * 2);
-        if (colors != null) {
-            // no mul by 2, since we need only 1 color per vertex
-            checkRange(colors.length, colorOffset, count);
-        }
-        nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
-                verts, vertOffset, colors, colorOffset,
-                paint != null ? paint.getNativeInstance() : 0);
-    }
-
-    @Override
-    public final void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
-        nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawColor(@ColorInt int color) {
-        nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
-    }
-
-    @Override
-    public final void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
-        nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt);
-    }
-
-    @Override
-    public final void drawLine(float startX, float startY, float stopX, float stopY,
-            @NonNull Paint paint) {
-        nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
-            @NonNull Paint paint) {
-        nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
-        drawLines(pts, 0, pts.length, paint);
-    }
-
-    @Override
-    public final void drawOval(float left, float top, float right, float bottom,
-            @NonNull Paint paint) {
-        nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
-        if (oval == null) {
-            throw new NullPointerException();
-        }
-        drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
-    }
-
-    @Override
-    public final void drawPaint(@NonNull Paint paint) {
-        nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst,
-            @Nullable Paint paint) {
-        Bitmap bitmap = patch.getBitmap();
-        throwIfCannotDraw(bitmap);
-        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
-        nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
-                dst.left, dst.top, dst.right, dst.bottom, nativePaint,
-                mDensity, patch.getDensity());
-    }
-
-    @Override
-    public final void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst,
-            @Nullable Paint paint) {
-        Bitmap bitmap = patch.getBitmap();
-        throwIfCannotDraw(bitmap);
-        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
-        nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
-                dst.left, dst.top, dst.right, dst.bottom, nativePaint,
-                mDensity, patch.getDensity());
-    }
-
-    @Override
-    public final void drawPath(@NonNull Path path, @NonNull Paint paint) {
-        if (path.isSimplePath && path.rects != null) {
-            nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
-        } else {
-            nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance());
-        }
-    }
-
-    @Override
-    public final void drawPicture(@NonNull Picture picture) {
-        picture.endRecording();
-        int restoreCount = save();
-        picture.draw(this);
-        restoreToCount(restoreCount);
-    }
-
-    @Override
-    public final void drawPicture(@NonNull Picture picture, @NonNull Rect dst) {
-        save();
-        translate(dst.left, dst.top);
-        if (picture.getWidth() > 0 && picture.getHeight() > 0) {
-            scale((float) dst.width() / picture.getWidth(),
-                    (float) dst.height() / picture.getHeight());
-        }
-        drawPicture(picture);
-        restore();
-    }
-
-    @Override
-    public final void drawPicture(@NonNull Picture picture, @NonNull RectF dst) {
-        save();
-        translate(dst.left, dst.top);
-        if (picture.getWidth() > 0 && picture.getHeight() > 0) {
-            scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
-        }
-        drawPicture(picture);
-        restore();
-    }
-
-    @Override
-    public final void drawPoint(float x, float y, @NonNull Paint paint) {
-        nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
-            @NonNull Paint paint) {
-        nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
-        drawPoints(pts, 0, pts.length, paint);
-    }
-
-    /** @deprecated checkstyle */
-    @Override
-    @Deprecated
-    public final void drawPosText(@NonNull char[] text, int index, int count,
-            @NonNull @Size(multiple = 2) float[] pos,
-            @NonNull Paint paint) {
-        if (index < 0 || index + count > text.length || count * 2 > pos.length) {
-            throw new IndexOutOfBoundsException();
-        }
-        for (int i = 0; i < count; i++) {
-            drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
-        }
-    }
-
-    /** @deprecated checkstyle */
-    @Override
-    @Deprecated
-    public final void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
-            @NonNull Paint paint) {
-        drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
-    }
-
-    @Override
-    public final void drawRect(float left, float top, float right, float bottom,
-            @NonNull Paint paint) {
-        nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawRect(@NonNull Rect r, @NonNull Paint paint) {
-        drawRect(r.left, r.top, r.right, r.bottom, paint);
-    }
-
-    @Override
-    public final void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
-        nDrawRect(mNativeCanvasWrapper,
-                rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawRGB(int r, int g, int b) {
-        drawColor(Color.rgb(r, g, b));
-    }
-
-    @Override
-    public final void drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, @NonNull Paint paint) {
-        nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
-                paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
-        drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
-    }
-
-    @Override
-    public final void drawText(@NonNull char[] text, int index, int count, float x, float y,
-            @NonNull Paint paint) {
-        if ((index | count | (index + count)
-                | (text.length - index - count)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
-                paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
-            @NonNull Paint paint) {
-        if ((start | end | (end - start) | (text.length() - end)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        if (text instanceof String || text instanceof SpannedString
-                || text instanceof SpannableString) {
-            nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
-                    paint.mBidiFlags, paint.getNativeInstance());
-        } else if (text instanceof GraphicsOperations) {
-            ((GraphicsOperations) text).drawText(this, start, end, x, y,
-                    paint);
-        } else {
-            char[] buf = TemporaryBuffer.obtain(end - start);
-            TextUtils.getChars(text, start, end, buf, 0);
-            nDrawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
-                    paint.mBidiFlags, paint.getNativeInstance());
-            TemporaryBuffer.recycle(buf);
-        }
-    }
-
-    @Override
-    public final void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
-        nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
-                paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawText(@NonNull String text, int start, int end, float x, float y,
-            @NonNull Paint paint) {
-        if ((start | end | (end - start) | (text.length() - end)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
-                paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
-            float hOffset, float vOffset, @NonNull Paint paint) {
-        if (index < 0 || index + count > text.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
-                path.readOnlyNI(), hOffset, vOffset,
-                paint.mBidiFlags, paint.getNativeInstance());
-    }
-
-    @Override
-    public final void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
-            float vOffset, @NonNull Paint paint) {
-        if (text.length() > 0) {
-            nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
-                    paint.mBidiFlags, paint.getNativeInstance());
-        }
-    }
-
-    @Override
-    public final void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
-            int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
-
-        if (text == null) {
-            throw new NullPointerException("text is null");
-        }
-        if (paint == null) {
-            throw new NullPointerException("paint is null");
-        }
-        if ((index | count | contextIndex | contextCount | index - contextIndex
-                | (contextIndex + contextCount) - (index + count)
-                | text.length - (contextIndex + contextCount)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
-                x, y, isRtl, paint.getNativeInstance(), 0 /* measured text */);
-    }
-
-    @Override
-    public final void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
-            int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
-
-        if (text == null) {
-            throw new NullPointerException("text is null");
-        }
-        if (paint == null) {
-            throw new NullPointerException("paint is null");
-        }
-        if ((start | end | contextStart | contextEnd | start - contextStart | end - start
-                | contextEnd - end | text.length() - contextEnd) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        if (text instanceof String || text instanceof SpannedString
-                || text instanceof SpannableString) {
-            nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
-                    contextEnd, x, y, isRtl, paint.getNativeInstance());
-        } else if (text instanceof GraphicsOperations) {
-            ((GraphicsOperations) text).drawTextRun(this, start, end,
-                    contextStart, contextEnd, x, y, isRtl, paint);
-        } else {
-            if (text instanceof PrecomputedText) {
-                final PrecomputedText pt = (PrecomputedText) text;
-                final int paraIndex = pt.findParaIndex(start);
-                if (end <= pt.getParagraphEnd(paraIndex)) {
-                    final int paraStart = pt.getParagraphStart(paraIndex);
-                    final MeasuredParagraph mp = pt.getMeasuredParagraph(paraIndex);
-                    // Only support if the target is in the same paragraph.
-                    nDrawTextRun(mNativeCanvasWrapper,
-                            mp.getChars(),
-                            start - paraStart,
-                            end - start,
-                            contextStart - paraStart,
-                            contextEnd - contextStart,
-                            x, y, isRtl, paint.getNativeInstance(),
-                            mp.getNativeMeasuredParagraph().getNativePtr());
-                    return;
-                }
-            }
-            int contextLen = contextEnd - contextStart;
-            int len = end - start;
-            char[] buf = TemporaryBuffer.obtain(contextLen);
-            TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
-            nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
-                    0, contextLen, x, y, isRtl, paint.getNativeInstance(),
-                    0 /* measured paragraph pointer */);
-            TemporaryBuffer.recycle(buf);
-        }
-    }
-
-    @Override
-    public final void drawVertices(@NonNull VertexMode mode, int vertexCount,
-            @NonNull float[] verts, int vertOffset, @Nullable float[] texs, int texOffset,
-            @Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset,
-            int indexCount, @NonNull Paint paint) {
-        checkRange(verts.length, vertOffset, vertexCount);
-        if (texs != null) {
-            checkRange(texs.length, texOffset, vertexCount);
-        }
-        if (colors != null) {
-            checkRange(colors.length, colorOffset, vertexCount / 2);
-        }
-        if (indices != null) {
-            checkRange(indices.length, indexOffset, indexCount);
-        }
-        nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
-                vertOffset, texs, texOffset, colors, colorOffset,
-                indices, indexOffset, indexCount, paint.getNativeInstance());
-    }
-
-    @FastNative
-    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
-            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
-
-    @FastNative
-    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap,
-            float srcLeft, float srcTop, float srcRight, float srcBottom,
-            float dstLeft, float dstTop, float dstRight, float dstBottom,
-            long nativePaintOrZero, int screenDensity, int bitmapDensity);
-
-    @FastNative
-    private static native void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
-            float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero);
-
-    @FastNative
-    private static native void nDrawColor(long nativeCanvas, int color, int mode);
-
-    @FastNative
-    private static native void nDrawPaint(long nativeCanvas, long nativePaint);
-
-    @FastNative
-    private static native void nDrawPoint(long canvasHandle, float x, float y, long paintHandle);
-
-    @FastNative
-    private static native void nDrawPoints(long canvasHandle, float[] pts, int offset, int count,
-            long paintHandle);
-
-    @FastNative
-    private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX,
-            float stopY, long nativePaint);
-
-    @FastNative
-    private static native void nDrawLines(long canvasHandle, float[] pts, int offset, int count,
-            long paintHandle);
-
-    @FastNative
-    private static native void nDrawRect(long nativeCanvas, float left, float top, float right,
-            float bottom, long nativePaint);
-
-    @FastNative
-    private static native void nDrawOval(long nativeCanvas, float left, float top, float right,
-            float bottom, long nativePaint);
-
-    @FastNative
-    private static native void nDrawCircle(long nativeCanvas, float cx, float cy, float radius,
-            long nativePaint);
-
-    @FastNative
-    private static native void nDrawArc(long nativeCanvas, float left, float top, float right,
-            float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint);
-
-    @FastNative
-    private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right,
-            float bottom, float rx, float ry, long nativePaint);
-
-    @FastNative
-    private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint);
-
-    @FastNative
-    private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint);
-
-    @FastNative
-    private static native void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
-            float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
-            int screenDensity, int bitmapDensity);
-
-    @FastNative
-    private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
-            long nativeMatrix, long nativePaint);
-
-    @FastNative
-    private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
-            int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
-            long nativePaint);
-
-    @FastNative
-    private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts,
-            int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
-            short[] indices, int indexOffset, int indexCount, long nativePaint);
-
-    @FastNative
-    private static native void nDrawText(long nativeCanvas, char[] text, int index, int count,
-            float x, float y, int flags, long nativePaint);
-
-    @FastNative
-    private static native void nDrawText(long nativeCanvas, String text, int start, int end,
-            float x, float y, int flags, long nativePaint);
-
-    @FastNative
-    private static native void nDrawTextRun(long nativeCanvas, String text, int start, int end,
-            int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint);
-
-    @FastNative
-    private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
-            int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
-            long nativePrecomputedText);
-
-    @FastNative
-    private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
-            long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint);
-
-    @FastNative
-    private static native void nDrawTextOnPath(long nativeCanvas, String text, long nativePath,
-            float hOffset, float vOffset, int flags, long nativePaint);
-}
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index fcea0c3..8ae9127 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -24,7 +24,6 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.graphics.drawable.AnimatedVectorDrawable;
 
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
@@ -148,12 +147,12 @@
      * @hide
      */
     final long mNativeRenderNode;
-    private final View mOwningView;
+    private final AnimationHost mAnimationHost;
 
-    private RenderNode(String name, View owningView) {
+    private RenderNode(String name, AnimationHost animationHost) {
         mNativeRenderNode = nCreate(name);
         NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
-        mOwningView = owningView;
+        mAnimationHost = animationHost;
     }
 
     /**
@@ -162,7 +161,7 @@
     private RenderNode(long nativePtr) {
         mNativeRenderNode = nativePtr;
         NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
-        mOwningView = null;
+        mAnimationHost = null;
     }
 
     /**
@@ -174,8 +173,8 @@
      * @return A new RenderNode.
      */
     @UnsupportedAppUsage
-    public static RenderNode create(String name, @Nullable View owningView) {
-        return new RenderNode(name, owningView);
+    public static RenderNode create(String name, @Nullable AnimationHost animationHost) {
+        return new RenderNode(name, animationHost);
     }
 
     /**
@@ -189,10 +188,37 @@
     }
 
     /**
+     * Listens for RenderNode position updates for synchronous window movement.
+     *
+     * This is not suitable for generic position listening, it is only designed & intended
+     * for use by things which require external position events like SurfaceView, PopupWindow, etc..
+     *
+     * @hide
+     */
+    interface PositionUpdateListener {
+
+        /**
+         * Called by native by a Rendering Worker thread to update window position
+         *
+         * @hide
+         */
+        void positionChanged(long frameNumber, int left, int top, int right, int bottom);
+
+        /**
+         * Called by native on RenderThread to notify that the view is no longer in the
+         * draw tree. UI thread is blocked at this point.
+         *
+         * @hide
+         */
+        void positionLost(long frameNumber);
+
+    }
+
+    /**
      * Enable callbacks for position changes.
      */
-    public void requestPositionUpdates(SurfaceView view) {
-        nRequestPositionUpdates(mNativeRenderNode, view);
+    public void requestPositionUpdates(PositionUpdateListener listener) {
+        nRequestPositionUpdates(mNativeRenderNode, listener);
     }
 
 
@@ -843,30 +869,72 @@
         return nGetDebugSize(mNativeRenderNode);
     }
 
+    /**
+     * Sets whether or not to allow force dark to apply to this RenderNode.
+     *
+     * Setting this to false will disable the auto-dark feature on everything this RenderNode
+     * draws, including any descendants.
+     *
+     * Setting this to true will allow this RenderNode 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.
+     *
+     * @param allow Whether or not to allow force dark.
+     * @return true If the value has changed, false otherwise.
+     */
+    public boolean setAllowForceDark(boolean allow) {
+        return nSetAllowForceDark(mNativeRenderNode, allow);
+    }
+
+    /**
+     * See {@link #setAllowForceDark(boolean)}
+     *
+     * @return true if force dark is allowed (default), false if it is disabled
+     */
+    public boolean getAllowForceDark() {
+        return nGetAllowForceDark(mNativeRenderNode);
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // Animations
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     * TODO: Figure out if this can be eliminated/refactored away
+     *
+     * For now this interface exists to de-couple RenderNode from anything View-specific in a
+     * bit of a kludge.
+     *
+     * @hide */
+    interface AnimationHost {
+        void registerAnimatingRenderNode(RenderNode animator);
+        void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);
+        boolean isAttached();
+    }
+
+    /** @hide */
     public void addAnimator(RenderNodeAnimator animator) {
-        if (mOwningView == null || mOwningView.mAttachInfo == null) {
+        if (!isAttached()) {
             throw new IllegalStateException("Cannot start this animator on a detached view!");
         }
         nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
-        mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
+        mAnimationHost.registerAnimatingRenderNode(this);
     }
 
+    /** @hide */
     public boolean isAttached() {
-        return mOwningView != null && mOwningView.mAttachInfo != null;
+        return mAnimationHost != null && mAnimationHost.isAttached();
     }
 
-    public void registerVectorDrawableAnimator(
-            AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet) {
-        if (mOwningView == null || mOwningView.mAttachInfo == null) {
+    /** @hide */
+    public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animatorSet) {
+        if (!isAttached()) {
             throw new IllegalStateException("Cannot start this animator on a detached view!");
         }
-        mOwningView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animatorSet);
+        mAnimationHost.registerVectorDrawableAnimator(animatorSet);
     }
 
+    /** @hide */
     public void endAllAnimators() {
         nEndAllAnimators(mNativeRenderNode);
     }
@@ -880,7 +948,8 @@
     private static native long nGetNativeFinalizer();
     private static native void nOutput(long renderNode);
     private static native int nGetDebugSize(long renderNode);
-    private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback);
+    private static native void nRequestPositionUpdates(long renderNode,
+            PositionUpdateListener callback);
 
     // Animations
 
@@ -1043,4 +1112,8 @@
     private static native int nGetWidth(long renderNode);
     @CriticalNative
     private static native int nGetHeight(long renderNode);
+    @CriticalNative
+    private static native boolean nSetAllowForceDark(long renderNode, boolean allowForceDark);
+    @CriticalNative
+    private static native boolean nGetAllowForceDark(long renderNode);
 }
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 427f570..6fb1bba 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -895,6 +895,7 @@
         HwuiContext(boolean isWideColorGamut) {
             mRenderNode = RenderNode.create("HwuiCanvas", null);
             mRenderNode.setClipToBounds(false);
+            mRenderNode.setAllowForceDark(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 79eafa8..0d33bbd 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -70,15 +70,8 @@
     private static native void nativeDestroy(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
 
-    private static native Bitmap nativeScreenshot(IBinder displayToken,
-            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
-            boolean allLayers, boolean useIdentityTransform, int rotation);
-    private static native GraphicBuffer nativeScreenshotToBuffer(IBinder displayToken,
-            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
-            boolean allLayers, boolean useIdentityTransform, int rotation);
-    private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
-            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
-            boolean allLayers, boolean useIdentityTransform);
+    private static native GraphicBuffer nativeScreenshot(IBinder displayToken,
+            Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation);
     private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
             Rect sourceCrop, float frameScale);
 
@@ -104,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);
@@ -952,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) {
@@ -1189,52 +1196,39 @@
     }
 
     /**
-     * Copy the current screen contents into the provided {@link Surface}
-     *
-     * @param display The display to take the screenshot of.
-     * @param consumer The {@link Surface} to take the screenshot into.
-     * @param width The desired width of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param height The desired height of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param minLayer The lowest (bottom-most Z order) surface layer to
-     * include in the screenshot.
-     * @param maxLayer The highest (top-most Z order) surface layer to
-     * include in the screenshot.
-     * @param useIdentityTransform Replace whatever transformation (rotation,
-     * scaling, translation) the surface layers are currently using with the
-     * identity transformation while taking the screenshot.
-     */
-    public static void screenshot(IBinder display, Surface consumer,
-            int width, int height, int minLayer, int maxLayer,
-            boolean useIdentityTransform) {
-        screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
-                false, useIdentityTransform);
-    }
-
-    /**
-     * Copy the current screen contents into the provided {@link Surface}
-     *
-     * @param display The display to take the screenshot of.
-     * @param consumer The {@link Surface} to take the screenshot into.
-     * @param width The desired width of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param height The desired height of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     */
-    public static void screenshot(IBinder display, Surface consumer,
-            int width, int height) {
-        screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
-    }
-
-    /**
-     * Copy the current screen contents into the provided {@link Surface}
-     *
-     * @param display The display to take the screenshot of.
-     * @param consumer The {@link Surface} to take the screenshot into.
+     * @see SurfaceControl#screenshot(IBinder, Surface, Rect, int, int, boolean, int)
      */
     public static void screenshot(IBinder display, Surface consumer) {
-        screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
+        screenshot(display, consumer, new Rect(), 0, 0, false, 0);
+    }
+
+    /**
+     * Copy the current screen contents into the provided {@link Surface}
+     *
+     * @param consumer The {@link Surface} to take the screenshot into.
+     * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)
+     */
+    public static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width,
+            int height, boolean useIdentityTransform, int rotation) {
+        if (consumer == null) {
+            throw new IllegalArgumentException("consumer must not be null");
+        }
+
+        final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height,
+                useIdentityTransform, rotation);
+        try {
+            consumer.attachAndQueueBuffer(buffer);
+        } catch (RuntimeException e) {
+            Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
+        }
+    }
+
+    /**
+     * @see SurfaceControl#screenshot(Rect, int, int, boolean, int)}
+     */
+    @UnsupportedAppUsage
+    public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) {
+        return screenshot(sourceCrop, width, height, false, rotation);
     }
 
     /**
@@ -1242,79 +1236,16 @@
      * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap into
      * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)}
      *
-     * CAVEAT: Versions of screenshot that return a {@link Bitmap} can
-     * be extremely slow; avoid use unless absolutely necessary; prefer
-     * the versions that use a {@link Surface} instead, such as
-     * {@link SurfaceControl#screenshot(IBinder, Surface)}.
+     * CAVEAT: Versions of screenshot that return a {@link Bitmap} can be extremely slow; avoid use
+     * unless absolutely necessary; prefer the versions that use a {@link Surface} such as
+     * {@link SurfaceControl#screenshot(IBinder, Surface)} or {@link GraphicBuffer} such as
+     * {@link SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}.
      *
-     * @param sourceCrop The portion of the screen to capture into the Bitmap;
-     * caller may pass in 'new Rect()' if no cropping is desired.
-     * @param width The desired width of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param height The desired height of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param minLayer The lowest (bottom-most Z order) surface layer to
-     * include in the screenshot.
-     * @param maxLayer The highest (top-most Z order) surface layer to
-     * include in the screenshot.
-     * @param useIdentityTransform Replace whatever transformation (rotation,
-     * scaling, translation) the surface layers are currently using with the
-     * identity transformation while taking the screenshot.
-     * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
-     * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
-     * screenshots in its native portrait orientation by default, so this is
-     * useful for returning screenshots that are independent of device
-     * orientation.
-     * @return Returns a hardware Bitmap containing the screen contents, or null
-     * if an error occurs. Make sure to call Bitmap.recycle() as soon as
-     * possible, once its content is not needed anymore.
+     * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}
      */
     @UnsupportedAppUsage
     public static Bitmap screenshot(Rect sourceCrop, int width, int height,
-            int minLayer, int maxLayer, boolean useIdentityTransform,
-            int rotation) {
-        // TODO: should take the display as a parameter
-        IBinder displayToken = SurfaceControl.getBuiltInDisplay(
-                SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
-        return nativeScreenshot(displayToken, sourceCrop, width, height,
-                minLayer, maxLayer, false, useIdentityTransform, rotation);
-    }
-
-    /**
-     * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)}
-     * but returns a GraphicBuffer.
-     */
-    public static GraphicBuffer screenshotToBuffer(Rect sourceCrop, int width, int height,
-            int minLayer, int maxLayer, boolean useIdentityTransform,
-            int rotation) {
-        IBinder displayToken = SurfaceControl.getBuiltInDisplay(
-                SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
-        return nativeScreenshotToBuffer(displayToken, sourceCrop, width, height,
-                minLayer, maxLayer, false, useIdentityTransform, rotation);
-    }
-
-    /**
-     * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)} but
-     * includes all Surfaces in the screenshot. This will also update the orientation so it
-     * sends the correct coordinates to SF based on the rotation value.
-     *
-     * @param sourceCrop The portion of the screen to capture into the Bitmap;
-     * caller may pass in 'new Rect()' if no cropping is desired.
-     * @param width The desired width of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param height The desired height of the returned bitmap; the raw
-     * screen will be scaled down to this size.
-     * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
-     * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
-     * screenshots in its native portrait orientation by default, so this is
-     * useful for returning screenshots that are independent of device
-     * orientation.
-     * @return Returns a Bitmap containing the screen contents, or null
-     * if an error occurs. Make sure to call Bitmap.recycle() as soon as
-     * possible, once its content is not needed anymore.
-     */
-    @UnsupportedAppUsage
-    public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) {
+            boolean useIdentityTransform, int rotation) {
         // TODO: should take the display as a parameter
         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
@@ -1323,22 +1254,45 @@
         }
 
         SurfaceControl.rotateCropForSF(sourceCrop, rotation);
-        return nativeScreenshot(displayToken, sourceCrop, width, height, 0, 0, true,
-                false, rotation);
+        final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height,
+                useIdentityTransform, rotation);
+
+        if (buffer == null) {
+            Log.w(TAG, "Failed to take screenshot");
+            return null;
+        }
+        return Bitmap.createHardwareBitmap(buffer);
     }
 
-    @UnsupportedAppUsage
-    private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
-            int width, int height, int minLayer, int maxLayer, boolean allLayers,
-            boolean useIdentityTransform) {
+    /**
+     * Captures all the surfaces in a display and returns a {@link GraphicBuffer} with the content.
+     *
+     * @param display              The display to take the screenshot of.
+     * @param sourceCrop           The portion of the screen to capture into the Bitmap; caller may
+     *                             pass in 'new Rect()' if no cropping is desired.
+     * @param width                The desired width of the returned bitmap; the raw screen will be
+     *                             scaled down to this size; caller may pass in 0 if no scaling is
+     *                             desired.
+     * @param height               The desired height of the returned bitmap; the raw screen will
+     *                             be scaled down to this size; caller may pass in 0 if no scaling
+     *                             is desired.
+     * @param useIdentityTransform Replace whatever transformation (rotation, scaling, translation)
+     *                             the surface layers are currently using with the identity
+     *                             transformation while taking the screenshot.
+     * @param rotation             Apply a custom clockwise rotation to the screenshot, i.e.
+     *                             Surface.ROTATION_0,90,180,270. SurfaceFlinger will always take
+     *                             screenshots in its native portrait orientation by default, so
+     *                             this is useful for returning screenshots that are independent of
+     *                             device orientation.
+     * @return Returns a GraphicBuffer that contains the captured content.
+     */
+    public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width,
+            int height, boolean useIdentityTransform, int rotation) {
         if (display == null) {
             throw new IllegalArgumentException("displayToken must not be null");
         }
-        if (consumer == null) {
-            throw new IllegalArgumentException("consumer must not be null");
-        }
-        nativeScreenshot(display, consumer, sourceCrop, width, height,
-                minLayer, maxLayer, allLayers, useIdentityTransform);
+
+        return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation);
     }
 
     private static void rotateCropForSF(Rect crop, int rot) {
@@ -1498,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 514a11e..e71182c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -209,7 +209,7 @@
 
     public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mRenderNode.requestPositionUpdates(this);
+        mRenderNode.requestPositionUpdates(mPositionListener);
 
         setWillNotDraw(true);
     }
@@ -826,81 +826,80 @@
 
     private Rect mRTLastReportedPosition = new Rect();
 
-    /**
-     * Called by native by a Rendering Worker thread to update the window position
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public final void updateSurfacePosition_renderWorker(long frameNumber,
-            int left, int top, int right, int bottom) {
-        if (mSurfaceControl == null) {
-            return;
-        }
+    private RenderNode.PositionUpdateListener mPositionListener =
+            new RenderNode.PositionUpdateListener() {
 
-        // TODO: This is teensy bit racey in that a brand new SurfaceView moving on
-        // its 2nd frame if RenderThread is running slowly could potentially see
-        // this as false, enter the branch, get pre-empted, then this comes along
-        // and reports a new position, then the UI thread resumes and reports
-        // its position. This could therefore be de-sync'd in that interval, but
-        // the synchronization would violate the rule that RT must never block
-        // on the UI thread which would open up potential deadlocks. The risk of
-        // a single-frame desync is therefore preferable for now.
-        mRtHandlingPositionUpdates = true;
-        if (mRTLastReportedPosition.left == left
-                && mRTLastReportedPosition.top == top
-                && mRTLastReportedPosition.right == right
-                && mRTLastReportedPosition.bottom == bottom) {
-            return;
-        }
-        try {
-            if (DEBUG) {
-                Log.d(TAG, String.format("%d updateSurfacePosition RenderWorker, frameNr = %d, " +
-                        "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                        frameNumber, left, top, right, bottom));
+        @Override
+        public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
+            if (mSurfaceControl == null) {
+                return;
             }
-            mRTLastReportedPosition.set(left, top, right, bottom);
-            setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
-            // Now overwrite mRTLastReportedPosition with our values
-        } catch (Exception ex) {
-            Log.e(TAG, "Exception from repositionChild", ex);
-        }
-    }
 
-    /**
-     * Called by native on RenderThread to notify that the view is no longer in the
-     * draw tree. UI thread is blocked at this point.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public final void surfacePositionLost_uiRtSync(long frameNumber) {
-        if (DEBUG) {
-            Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
-                    System.identityHashCode(this), frameNumber));
+            // TODO: This is teensy bit racey in that a brand new SurfaceView moving on
+            // its 2nd frame if RenderThread is running slowly could potentially see
+            // this as false, enter the branch, get pre-empted, then this comes along
+            // and reports a new position, then the UI thread resumes and reports
+            // its position. This could therefore be de-sync'd in that interval, but
+            // the synchronization would violate the rule that RT must never block
+            // on the UI thread which would open up potential deadlocks. The risk of
+            // a single-frame desync is therefore preferable for now.
+            mRtHandlingPositionUpdates = true;
+            if (mRTLastReportedPosition.left == left
+                    && mRTLastReportedPosition.top == top
+                    && mRTLastReportedPosition.right == right
+                    && mRTLastReportedPosition.bottom == bottom) {
+                return;
+            }
+            try {
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "%d updateSurfacePosition RenderWorker, frameNr = %d, "
+                                    + "postion = [%d, %d, %d, %d]",
+                            System.identityHashCode(this), frameNumber,
+                            left, top, right, bottom));
+                }
+                mRTLastReportedPosition.set(left, top, right, bottom);
+                setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
+                // Now overwrite mRTLastReportedPosition with our values
+            } catch (Exception ex) {
+                Log.e(TAG, "Exception from repositionChild", ex);
+            }
         }
-        mRTLastReportedPosition.setEmpty();
 
-        if (mSurfaceControl == null) {
-            return;
-        }
-        if (mRtHandlingPositionUpdates) {
-            mRtHandlingPositionUpdates = false;
-            // This callback will happen while the UI thread is blocked, so we can
-            // safely access other member variables at this time.
-            // So do what the UI thread would have done if RT wasn't handling position
-            // updates.
-            if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
-                try {
-                    if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition, " +
-                            "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                            mScreenRect.left, mScreenRect.top,
-                            mScreenRect.right, mScreenRect.bottom));
-                    setParentSpaceRectangle(mScreenRect, frameNumber);
-                } catch (Exception ex) {
-                    Log.e(TAG, "Exception configuring surface", ex);
+        @Override
+        public void positionLost(long frameNumber) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
+                        System.identityHashCode(this), frameNumber));
+            }
+            mRTLastReportedPosition.setEmpty();
+
+            if (mSurfaceControl == null) {
+                return;
+            }
+            if (mRtHandlingPositionUpdates) {
+                mRtHandlingPositionUpdates = false;
+                // This callback will happen while the UI thread is blocked, so we can
+                // safely access other member variables at this time.
+                // So do what the UI thread would have done if RT wasn't handling position
+                // updates.
+                if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
+                    try {
+                        if (DEBUG) {
+                            Log.d(TAG, String.format("%d updateSurfacePosition, "
+                                            + "postion = [%d, %d, %d, %d]",
+                                    System.identityHashCode(this),
+                                    mScreenRect.left, mScreenRect.top,
+                                    mScreenRect.right, mScreenRect.bottom));
+                        }
+                        setParentSpaceRectangle(mScreenRect, frameNumber);
+                    } catch (Exception ex) {
+                        Log.e(TAG, "Exception configuring surface", ex);
+                    }
                 }
             }
         }
-    }
+    };
 
     private SurfaceHolder.Callback[] getSurfaceCallbacks() {
         SurfaceHolder.Callback callbacks[];
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 6737839..42690ce 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -25,7 +25,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.graphics.drawable.AnimatedVectorDrawable;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -914,8 +913,7 @@
         nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
     }
 
-    void registerVectorDrawableAnimator(
-        AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
+    void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
         nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
                 animator.getAnimatorNativePtr());
     }
@@ -976,6 +974,25 @@
         }
     }
 
+    /** The root of everything */
+    public @NonNull RenderNode getRootNode() {
+        return mRootNode;
+    }
+
+    private boolean mForceDark = false;
+
+    /**
+     * Whether or not the force-dark feature should be used for this renderer.
+     */
+    public boolean setForceDark(boolean enable) {
+        if (mForceDark != enable) {
+            mForceDark = enable;
+            nSetForceDark(mNativeProxy, enable);
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Basic synchronous renderer. Currently only used to render the Magnifier, so use with care.
      * TODO: deduplicate against ThreadedRenderer.
@@ -1255,4 +1272,5 @@
     private static native void nSetIsolatedProcess(boolean enabled);
     private static native void nSetContextPriority(int priority);
     private static native void nAllocateBuffers(long nativeProxy, Surface window);
+    private static native void nSetForceDark(long nativeProxy, boolean enabled);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 19e3f7f62..cddd83c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4864,7 +4864,7 @@
         setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
         mUserPaddingStart = UNDEFINED_PADDING;
         mUserPaddingEnd = UNDEFINED_PADDING;
-        mRenderNode = RenderNode.create(getClass().getName(), this);
+        mRenderNode = RenderNode.create(getClass().getName(), new ViewAnimationHostBridge(this));
 
         if (!sCompatibilityDone && context != null) {
             final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
@@ -5732,7 +5732,7 @@
     @UnsupportedAppUsage
     View() {
         mResources = null;
-        mRenderNode = RenderNode.create(getClass().getName(), this);
+        mRenderNode = RenderNode.create(getClass().getName(), new ViewAnimationHostBridge(this));
     }
 
     final boolean debugDraw() {
@@ -14639,9 +14639,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();
     }
 
@@ -15246,6 +15247,44 @@
     }
 
     /**
+     * Sets whether or not to allow force dark to apply to this view.
+     *
+     * Setting this to false will disable the auto-dark feature on everything this view
+     * draws, including any descendants.
+     *
+     * 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.
+     *
+     * The default behavior of force dark is also influenced by the Theme's
+     * {@link android.R.styleable#Theme_isLightTheme isLightTheme} attribute.
+     * 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)) {
+            // 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();
+        }
+    }
+
+    /**
+     * See {@link #setAllowForceDark(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();
+    }
+
+    /**
      * Top position of this view relative to its parent.
      *
      * @return The top of this view, in pixels.
@@ -15598,7 +15637,7 @@
     /**
      * Sets the visual z position of this view, in pixels. This is equivalent to setting the
      * {@link #setTranslationZ(float) translationZ} property to be the difference between
-     * the x value passed in and the current {@link #getElevation() elevation} property.
+     * the z value passed in and the current {@link #getElevation() elevation} property.
      *
      * @param z The visual z position of this view, in pixels.
      */
@@ -20566,7 +20605,8 @@
      */
     private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
         if (renderNode == null) {
-            renderNode = RenderNode.create(drawable.getClass().getName(), this);
+            renderNode = RenderNode.create(drawable.getClass().getName(),
+                    new ViewAnimationHostBridge(this));
             renderNode.setUsageHint(RenderNode.USAGE_BACKGROUND);
         }
 
diff --git a/core/java/android/view/ViewAnimationHostBridge.java b/core/java/android/view/ViewAnimationHostBridge.java
new file mode 100644
index 0000000..58f555d
--- /dev/null
+++ b/core/java/android/view/ViewAnimationHostBridge.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 android.view;
+
+/**
+ * Maps a View to a RenderNode's AnimationHost
+ *
+ * @hide
+ */
+public class ViewAnimationHostBridge implements RenderNode.AnimationHost {
+    private final View mView;
+
+    /**
+     * @param view the View to bridge to an AnimationHost
+     */
+    public ViewAnimationHostBridge(View view) {
+        mView = view;
+    }
+
+    @Override
+    public void registerAnimatingRenderNode(RenderNode animator) {
+        mView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(animator);
+    }
+
+    @Override
+    public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
+        mView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animator);
+    }
+
+    @Override
+    public boolean isAttached() {
+        return mView.mAttachInfo != null;
+    }
+}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2ee7ab9..bef8e8f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -43,6 +43,7 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Matrix;
@@ -52,7 +53,6 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -239,6 +239,12 @@
     final ArrayList<WindowCallbacks> mWindowCallbacks = new ArrayList<>();
     @UnsupportedAppUsage
     final Context mContext;
+    /**
+     * TODO(b/116349163): Check if we can merge this into {@link #mContext}.
+     */
+    @NonNull
+    private Context mDisplayContext;
+
     @UnsupportedAppUsage
     final IWindowSession mWindowSession;
     @NonNull Display mDisplay;
@@ -532,6 +538,7 @@
 
     public ViewRootImpl(Context context, Display display) {
         mContext = context;
+        mDisplayContext = context.createDisplayContext(display);
         mWindowSession = WindowManagerGlobal.getWindowSession();
         mDisplay = display;
         mBasePackageName = context.getBasePackageName();
@@ -984,6 +991,9 @@
         ThreadedRenderer.invokeFunctor(functor, waitForCompletion);
     }
 
+    /**
+     * @param animator animator to register with the hardware renderer
+     */
     public void registerAnimatingRenderNode(RenderNode animator) {
         if (mAttachInfo.mThreadedRenderer != null) {
             mAttachInfo.mThreadedRenderer.registerAnimatingRenderNode(animator);
@@ -995,8 +1005,10 @@
         }
     }
 
-    public void registerVectorDrawableAnimator(
-            AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
+    /**
+     * @param animator animator to register with the hardware renderer
+     */
+    public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
         if (mAttachInfo.mThreadedRenderer != null) {
             mAttachInfo.mThreadedRenderer.registerVectorDrawableAnimator(animator);
         }
@@ -1066,6 +1078,7 @@
                 mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
                         attrs.getTitle().toString());
                 mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
+                updateForceDarkMode();
                 if (mAttachInfo.mThreadedRenderer != null) {
                     mAttachInfo.mHardwareAccelerated =
                             mAttachInfo.mHardwareAccelerationRequested = true;
@@ -1074,6 +1087,27 @@
         }
     }
 
+    private int getNightMode() {
+        return mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+    }
+
+    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 changed = mAttachInfo.mThreadedRenderer.setForceDark(nightMode);
+        changed |= mAttachInfo.mThreadedRenderer.getRootNode().setAllowForceDark(isLightTheme);
+
+        if (changed) {
+            // TODO: Don't require regenerating all display lists to apply this setting
+            invalidateWorld(mView);
+        }
+    }
+
     @UnsupportedAppUsage
     public View getView() {
         return mView;
@@ -1249,6 +1283,7 @@
         } else {
             mDisplay = preferredDisplay;
         }
+        mDisplayContext = mContext.createDisplayContext(mDisplay);
     }
 
     void pokeDrawLockIfNeeded() {
@@ -2579,7 +2614,7 @@
                     .mayUseInputMethod(mWindowAttributes.flags);
             if (imTarget != mLastWasImTarget) {
                 mLastWasImTarget = imTarget;
-                InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
+                InputMethodManager imm = mDisplayContext.getSystemService(InputMethodManager.class);
                 if (imm != null && imTarget) {
                     imm.onPreWindowFocus(mView, hasWindowFocus);
                     imm.onPostWindowFocus(mView, mView.findFocus(),
@@ -2695,7 +2730,7 @@
             mLastWasImTarget = WindowManager.LayoutParams
                     .mayUseInputMethod(mWindowAttributes.flags);
 
-            InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
+            InputMethodManager imm = mDisplayContext.getSystemService(InputMethodManager.class);
             if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
                 imm.onPreWindowFocus(mView, hasWindowFocus);
             }
@@ -4065,6 +4100,8 @@
             mForceNextWindowRelayout = true;
             requestLayout();
         }
+
+        updateForceDarkMode();
     }
 
     /**
@@ -4329,7 +4366,8 @@
                     enqueueInputEvent(event, null, 0, true);
                 } break;
                 case MSG_CHECK_FOCUS: {
-                    InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
+                    InputMethodManager imm =
+                            mDisplayContext.getSystemService(InputMethodManager.class);
                     if (imm != null) {
                         imm.checkFocus();
                     }
@@ -4871,7 +4909,7 @@
         @Override
         protected int onProcess(QueuedInputEvent q) {
             if (mLastWasImTarget && !isInLocalFocusMode()) {
-                InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
+                InputMethodManager imm = mDisplayContext.getSystemService(InputMethodManager.class);
                 if (imm != null) {
                     final InputEvent event = q.mEvent;
                     if (DEBUG_IMF) Log.v(mTag, "Sending input event to IME: " + event);
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index e20acf1..46aea80 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -196,7 +196,10 @@
         synchronized (WindowManagerGlobal.class) {
             if (sWindowSession == null) {
                 try {
-                    InputMethodManager imm = InputMethodManager.getInstance();
+                    // Emulate the legacy behavior.  The global instance of InputMethodManager
+                    // was instantiated here.
+                    // TODO(b/116157766): Remove this hack after cleaning up @UnsupportedAppUsage
+                    InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();
                     IWindowManager windowManager = getWindowManagerService();
                     sWindowSession = windowManager.openSession(
                             new IWindowSessionCallback.Stub() {
@@ -204,8 +207,7 @@
                                 public void onAnimatorScaleChanged(float scale) {
                                     ValueAnimator.setDurationScale(scale);
                                 }
-                            },
-                            imm.getClient(), imm.getInputContext());
+                            });
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 87b7b05..0e1f767 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -203,11 +203,6 @@
      */
     private float mScaleFactor = 1f;
 
-    /**
-     * Don't animate the wallpaper.
-     */
-    private boolean mDetachWallpaper = false;
-
     private boolean mShowWallpaper;
 
     private boolean mMore = true;
@@ -667,9 +662,10 @@
      *
      * @param detachWallpaper true if the wallpaper should be detached from the animation
      * @attr ref android.R.styleable#Animation_detachWallpaper
+     *
+     * @deprecated All window animations are running with detached wallpaper.
      */
     public void setDetachWallpaper(boolean detachWallpaper) {
-        mDetachWallpaper = detachWallpaper;
     }
 
     /**
@@ -793,9 +789,11 @@
     /**
      * Return value of {@link #setDetachWallpaper(boolean)}.
      * @attr ref android.R.styleable#Animation_detachWallpaper
+     *
+     * @deprecated All window animations are running with detached wallpaper.
      */
     public boolean getDetachWallpaper() {
-        return mDetachWallpaper;
+        return false;
     }
 
     /**
diff --git a/core/java/android/view/animation/DecelerateInterpolator.java b/core/java/android/view/animation/DecelerateInterpolator.java
index f89743c..2d1249d 100644
--- a/core/java/android/view/animation/DecelerateInterpolator.java
+++ b/core/java/android/view/animation/DecelerateInterpolator.java
@@ -41,8 +41,8 @@
      * Constructor
      *
      * @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces
-     *        an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
-     *        ease-out effect (i.e., it starts even faster and ends evens slower)
+     *        an upside-down y=x^2 parabola. Increasing factor above 1.0f exaggerates the
+     *        ease-out effect (i.e., it starts even faster and ends evens slower).
      */
     public DecelerateInterpolator(float factor) {
         mFactor = factor;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index e87048e..d4c7069 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -301,6 +301,14 @@
      */
     public static final int STATE_UNKNOWN_COMPAT_MODE = 5;
 
+    /**
+     * Same as {@link #STATE_UNKNOWN}, but used on
+     * {@link AutofillManagerClient#setSessionFinished(int)} when the session was finished because
+     * the service failed to fullfil a request.
+     *
+     * @hide
+     */
+    public static final int STATE_UNKNOWN_FAILED = 6;
 
     /**
      * Timeout in ms for calls to the field classification service.
@@ -795,10 +803,6 @@
                 return true;
             }
         }
-        if (sVerbose) {
-            Log.v(TAG, "not ignoring notifyViewEntered(flags=" + flags + ", view=" + id
-                    + ", state " + getStateAsStringLocked() + ", enteredIds=" + mEnteredIds);
-        }
         return false;
     }
 
@@ -837,6 +841,9 @@
         ensureServiceClientAddedIfNeededLocked();
 
         if (!mEnabled) {
+            if (sVerbose) {
+                Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled");
+            }
             if (mCallback != null) {
                 callback = mCallback;
             }
@@ -987,6 +994,9 @@
         ensureServiceClientAddedIfNeededLocked();
 
         if (!mEnabled) {
+            if (sVerbose) {
+                Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled");
+            }
             if (mCallback != null) {
                 callback = mCallback;
             }
@@ -2023,8 +2033,10 @@
      * @param newState {@link #STATE_FINISHED} (because the autofill service returned a {@code null}
      *  FillResponse), {@link #STATE_UNKNOWN} (because the session was removed),
      *  {@link #STATE_UNKNOWN_COMPAT_MODE} (beucase the session was finished when the URL bar
-     *  changed on compat mode), or {@link #STATE_DISABLED_BY_SERVICE} (because the autofill service
-     *  disabled further autofill requests for the activity).
+     *  changed on compat mode), {@link #STATE_UNKNOWN_FAILED} (because the session was finished
+     *  when the service failed to fullfil the request, or {@link #STATE_DISABLED_BY_SERVICE}
+     *  (because the autofill service or {@link #STATE_DISABLED_BY_SERVICE} (because the autofill
+     *  service disabled further autofill requests for the activity).
      */
     private void setSessionFinished(int newState) {
         synchronized (mLock) {
@@ -2032,7 +2044,7 @@
                 Log.v(TAG, "setSessionFinished(): from " + getStateAsStringLocked() + " to "
                         + getStateAsString(newState));
             }
-            if (newState == STATE_UNKNOWN_COMPAT_MODE) {
+            if (newState == STATE_UNKNOWN_COMPAT_MODE || newState == STATE_UNKNOWN_FAILED) {
                 resetSessionLocked(/* resetEnteredIds= */ true);
                 mState = STATE_UNKNOWN;
             } else {
@@ -2229,6 +2241,8 @@
                 return "DISABLED_BY_SERVICE";
             case STATE_UNKNOWN_COMPAT_MODE:
                 return "UNKNOWN_COMPAT_MODE";
+            case STATE_UNKNOWN_FAILED:
+                return "UNKNOWN_FAILED";
             default:
                 return "INVALID:" + state;
         }
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index e1600c4..d09323d 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -124,7 +124,8 @@
      * @hide
      */
     @MainThread
-    public void updateInputMethodDisplay(int displayId);
+    default void updateInputMethodDisplay(int displayId) {
+    }
 
     /**
      * Bind a new application environment in to the input method, so that it
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 02ada94..08ed9d1 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;
@@ -57,7 +58,7 @@
 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 import android.view.autofill.AutofillManager;
 
-import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.view.IInputConnectionWrapper;
@@ -70,6 +71,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -226,10 +228,69 @@
 
     static final String PENDING_EVENT_COUNTER = "aq:imm";
 
+    /**
+     * Ensures that {@link #sInstance} becomes non-{@code null} for application that have directly
+     * or indirectly relied on {@link #sInstance} via reflection or something like that.
+     *
+     * <p>Here are scenarios we know and there could be more scenarios we are not
+     * aware of right know.</p>
+     *
+     * <ul>
+     *     <li>Apps that directly access {@link #sInstance} via reflection, which is currently
+     *     allowed because of {@link UnsupportedAppUsage} annotation.  Currently
+     *     {@link android.view.WindowManagerGlobal#getWindowSession()} is likely to guarantee that
+     *     {@link #sInstance} is not {@code null} when such an app is accessing it, but removing
+     *     that code from {@link android.view.WindowManagerGlobal#getWindowSession()} can reveal
+     *     untested code paths in their apps, which probably happen in an early startup time of that
+     *     app.</li>
+     *     <li>Apps that directly access {@link #peekInstance()} via reflection, which is currently
+     *     allowed because of {@link UnsupportedAppUsage} annotation.  Currently
+     *     {@link android.view.WindowManagerGlobal#getWindowSession()} is likely to guarantee that
+     *     {@link #peekInstance()} returns non-{@code null} object when such an app is calling
+     *     {@link #peekInstance()}, but removing that code from
+     *     {@link android.view.WindowManagerGlobal#getWindowSession()} can reveal untested code
+     *     paths in their apps, which probably happen in an early startup time of that app. The good
+     *     news is that unlike {@link #sInstance}'s case we can at least work around this scenario
+     *     by changing the semantics of {@link #peekInstance()}, which is currently defined as
+     *     "retrieve the global {@link InputMethodManager} instance, if it exists" to something that
+     *     always returns non-{@code null} {@link InputMethodManager}.  However, introducing such an
+     *     workaround can also trigger different compatibility issues if {@link #peekInstance()} was
+     *     called before {@link android.view.WindowManagerGlobal#getWindowSession()} and it expected
+     *     {@link #peekInstance()} to return {@code null} as written in the JavaDoc.</li>
+     * </ul>
+     *
+     * <p>Since this is purely a compatibility hack, this method must be used only from
+     * {@link android.view.WindowManagerGlobal#getWindowSession()} and {@link #getInstance()}.</p>
+     *
+     * <p>TODO(Bug 116157766): Remove this method once we clean up {@link UnsupportedAppUsage}.</p>
+     * @hide
+     */
+    public static void ensureDefaultInstanceForDefaultDisplayIfNecessary() {
+        forContextInternal(Display.DEFAULT_DISPLAY, Looper.getMainLooper());
+    }
+
+    private static final Object sLock = new Object();
+
+    /**
+     * @deprecated This cannot be compatible with multi-display. Please do not use this.
+     */
+    @Deprecated
+    @GuardedBy("sLock")
     @UnsupportedAppUsage
     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.
      */
@@ -286,6 +347,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.
      */
@@ -387,9 +450,6 @@
     final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
     final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
 
-    private final InputMethodPrivilegedOperationsRegistry mPrivOpsRegistry =
-            new InputMethodPrivilegedOperationsRegistry();
-
     // -----------------------------------------------------------
 
     static final int MSG_DUMP = 1;
@@ -406,6 +466,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 = getDisplayId(view.getContext());
+        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.
@@ -632,48 +715,152 @@
 
     final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
 
-    InputMethodManager(Looper looper) throws ServiceNotFoundException {
-        this(IInputMethodManager.Stub.asInterface(
-                ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE)), looper);
-    }
-
-    InputMethodManager(IInputMethodManager service, Looper looper) {
-        mService = service;
-        mMainLooper = looper;
-        mH = new H(looper);
-        mIInputContext = new ControlledInputConnectionWrapper(looper,
-                mDummyInputConnection, this);
-    }
-
     /**
-     * Retrieve the global InputMethodManager instance, creating it if it
-     * doesn't already exist.
-     * @hide
+     * For layoutlib to clean up static objects inside {@link InputMethodManager}.
      */
-    @UnsupportedAppUsage
-    public static InputMethodManager getInstance() {
-        synchronized (InputMethodManager.class) {
-            if (sInstance == null) {
-                try {
-                    sInstance = new InputMethodManager(Looper.getMainLooper());
-                } catch (ServiceNotFoundException e) {
-                    throw new IllegalStateException(e);
-                }
-            }
-            return sInstance;
+    static void tearDownEditMode() {
+        if (!isInEditMode()) {
+            throw new UnsupportedOperationException(
+                    "This method must be called only from layoutlib");
+        }
+        synchronized (sLock) {
+            sInstance = null;
         }
     }
 
     /**
-     * Private optimization: retrieve the global InputMethodManager instance, if it exists.
+     * For layoutlib to override this method to return {@code true}.
+     *
+     * @return {@code true} if the process is running for developer tools
+     * @see View#isInEditMode()
+     */
+    private static boolean isInEditMode() {
+        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;
+                    }
+                });
+    }
+
+    InputMethodManager(int displayId, Looper looper) throws ServiceNotFoundException {
+        mService = getIInputMethodManager();
+        mMainLooper = looper;
+        mH = new H(looper);
+        mDisplayId = displayId;
+        mIInputContext = new ControlledInputConnectionWrapper(looper,
+                mDummyInputConnection, this);
+    }
+
+    private static int getDisplayId(Context context) {
+        final Display display = context.getDisplay();
+        return display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
+    }
+
+    /**
+     * Retrieve an instance for the given {@link Context}, creating it if it doesn't already exist.
+     *
+     * @param context {@link Context} for which IME APIs need to work
+     * @return {@link InputMethodManager} instance
      * @hide
+     */
+    @Nullable
+    public static InputMethodManager forContext(Context context) {
+        final int displayId = getDisplayId(context);
+        // 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);
+    }
+
+    @Nullable
+    private static InputMethodManager forContextInternal(int displayId, Looper looper) {
+        final boolean isDefaultDisplay = displayId == Display.DEFAULT_DISPLAY;
+        synchronized (sLock) {
+            InputMethodManager instance = sInstanceMap.get(displayId);
+            if (instance != null) {
+                return instance;
+            }
+            try {
+                instance = new InputMethodManager(displayId, looper);
+                instance.mService.addClient(instance.mClient, instance.mIInputContext, displayId);
+            } catch (ServiceNotFoundException | RemoteException e) {
+                throw new IllegalStateException(e);
+            }
+            // For backward compatibility, store the instance also to sInstance for default display.
+            if (sInstance == null && isDefaultDisplay) {
+                sInstance = instance;
+            }
+            sInstanceMap.put(displayId, instance);
+            return instance;
+        }
+    }
+
+    /**
+     * Deprecated. Do not use.
+     *
+     * @return global {@link InputMethodManager} instance
      * @deprecated Use {@link Context#getSystemService(Class)} instead. This method cannot fully
      *             support multi-display scenario.
+     * @hide
+     */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static InputMethodManager getInstance() {
+        Log.w(TAG, "InputMethodManager.getInstance() is deprecated because it cannot be"
+                        + " compatible with multi-display."
+                        + " Use context.getSystemService(InputMethodManager.class) instead.",
+                new Throwable());
+        ensureDefaultInstanceForDefaultDisplayIfNecessary();
+        return peekInstance();
+    }
+
+    /**
+     * Deprecated. Do not use.
+     *
+     * @return {@link #sInstance}
+     * @deprecated Use {@link Context#getSystemService(Class)} instead. This method cannot fully
+     *             support multi-display scenario.
+     * @hide
      */
     @Deprecated
     @UnsupportedAppUsage
     public static InputMethodManager peekInstance() {
-        return sInstance;
+        Log.w(TAG, "InputMethodManager.peekInstance() is deprecated because it cannot be"
+                        + " compatible with multi-display."
+                        + " Use context.getSystemService(InputMethodManager.class) instead.",
+                new Throwable());
+        synchronized (sLock) {
+            return sInstance;
+        }
     }
 
     /** @hide */
@@ -741,7 +928,7 @@
      */
     @Deprecated
     public void showStatusIcon(IBinder imeToken, String packageName, @DrawableRes int iconId) {
-        mPrivOpsRegistry.get(imeToken).updateStatusIcon(packageName, iconId);
+        InputMethodPrivilegedOperationsRegistry.get(imeToken).updateStatusIcon(packageName, iconId);
     }
 
     /**
@@ -751,7 +938,7 @@
      */
     @Deprecated
     public void hideStatusIcon(IBinder imeToken) {
-        mPrivOpsRegistry.get(imeToken).updateStatusIcon(null, 0);
+        InputMethodPrivilegedOperationsRegistry.get(imeToken).updateStatusIcon(null, 0);
     }
 
     /** @hide */
@@ -790,6 +977,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
@@ -880,6 +1072,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
@@ -898,6 +1097,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
@@ -939,6 +1145,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);
     }
 
@@ -1001,6 +1213,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
@@ -1164,6 +1382,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
@@ -1352,6 +1576,10 @@
                     mServedView.getWindowToken() == appWindowToken) {
                 finishInputLocked();
             }
+            if (mCurRootView != null &&
+                    mCurRootView.getWindowToken() == appWindowToken) {
+                mCurRootView = null;
+            }
         }
     }
 
@@ -1584,6 +1812,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
@@ -1621,6 +1856,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) {
@@ -1685,6 +1926,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
@@ -1716,6 +1964,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 &&
@@ -1761,6 +2016,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
@@ -1792,7 +2054,7 @@
     public void setInputMethod(IBinder token, String id) {
         if (token == null) {
             // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
-            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
+            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
             // TODO(Bug 114488811): Consider deprecating null token rule.
             try {
                 mService.setInputMethod(token, id);
@@ -1801,7 +2063,7 @@
             }
             return;
         }
-        mPrivOpsRegistry.get(token).setInputMethod(id);
+        InputMethodPrivilegedOperationsRegistry.get(token).setInputMethod(id);
     }
 
     /**
@@ -1821,7 +2083,7 @@
     public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
         if (token == null) {
             // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
-            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
+            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
             // TODO(Bug 114488811): Consider deprecating null token rule.
             try {
                 mService.setInputMethodAndSubtype(token, id, subtype);
@@ -1830,7 +2092,7 @@
             }
             return;
         }
-        mPrivOpsRegistry.get(token).setInputMethodAndSubtype(id, subtype);
+        InputMethodPrivilegedOperationsRegistry.get(token).setInputMethodAndSubtype(id, subtype);
     }
 
     /**
@@ -1850,7 +2112,7 @@
      */
     @Deprecated
     public void hideSoftInputFromInputMethod(IBinder token, int flags) {
-        mPrivOpsRegistry.get(token).hideMySoftInput(flags);
+        InputMethodPrivilegedOperationsRegistry.get(token).hideMySoftInput(flags);
     }
 
     /**
@@ -1871,7 +2133,7 @@
      */
     @Deprecated
     public void showSoftInputFromInputMethod(IBinder token, int flags) {
-        mPrivOpsRegistry.get(token).showMySoftInput(flags);
+        InputMethodPrivilegedOperationsRegistry.get(token).showMySoftInput(flags);
     }
 
     /**
@@ -1932,6 +2194,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) {
@@ -2231,7 +2500,7 @@
     public boolean switchToLastInputMethod(IBinder imeToken) {
         if (imeToken == null) {
             // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
-            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
+            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
             // TODO(Bug 114488811): Consider deprecating null token rule.
             try {
                 return mService.switchToPreviousInputMethod(imeToken);
@@ -2239,7 +2508,7 @@
                 throw e.rethrowFromSystemServer();
             }
         }
-        return mPrivOpsRegistry.get(imeToken).switchToPreviousInputMethod();
+        return InputMethodPrivilegedOperationsRegistry.get(imeToken).switchToPreviousInputMethod();
     }
 
     /**
@@ -2259,7 +2528,7 @@
     public boolean switchToNextInputMethod(IBinder imeToken, boolean onlyCurrentIme) {
         if (imeToken == null) {
             // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
-            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
+            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
             // TODO(Bug 114488811): Consider deprecating null token rule.
             try {
                 return mService.switchToNextInputMethod(imeToken, onlyCurrentIme);
@@ -2267,7 +2536,8 @@
                 throw e.rethrowFromSystemServer();
             }
         }
-        return mPrivOpsRegistry.get(imeToken).switchToNextInputMethod(onlyCurrentIme);
+        return InputMethodPrivilegedOperationsRegistry.get(imeToken)
+                .switchToNextInputMethod(onlyCurrentIme);
     }
 
     /**
@@ -2286,7 +2556,8 @@
      */
     @Deprecated
     public boolean shouldOfferSwitchingToNextInputMethod(IBinder imeToken) {
-        return mPrivOpsRegistry.get(imeToken).shouldOfferSwitchingToNextInputMethod();
+        return InputMethodPrivilegedOperationsRegistry.get(imeToken)
+                .shouldOfferSwitchingToNextInputMethod();
     }
 
     /**
@@ -2419,37 +2690,8 @@
         sb.append(",windowFocus=" + view.hasWindowFocus());
         sb.append(",autofillUiShowing=" + isAutofillUIShowing(view));
         sb.append(",window=" + view.getWindowToken());
+        sb.append(",displayId=" + getDisplayId(view.getContext()));
         sb.append(",temporaryDetach=" + view.isTemporarilyDetached());
         return sb.toString();
     }
-
-    /**
-     * Called by {@link InputMethodService} so that API calls to deprecated ones defined in this
-     * class can be forwarded to {@link InputMethodPrivilegedOperations}.
-     *
-     * <p>Note: this method does not hold strong references to {@code token} and {@code ops}. The
-     * registry entry will be automatically cleared after {@code token} is garbage collected.</p>
-     *
-     * @param token IME token that is associated with {@code ops}
-     * @param ops {@link InputMethodPrivilegedOperations} that is associated with {@code token}
-     * @hide
-     */
-    public void registerInputMethodPrivOps(IBinder token, InputMethodPrivilegedOperations ops) {
-        mPrivOpsRegistry.put(token, ops);
-    }
-
-    /**
-     * Called from {@link InputMethodService#onDestroy()} to make sure that deprecated IME APIs
-     * defined in this class can no longer access to {@link InputMethodPrivilegedOperations}.
-     *
-     * <p>Note: Calling this method is optional, but at least gives more explict error message in
-     * logcat when IME developers are doing something unsupported (e.g. trying to call IME APIs
-     * after {@link InputMethodService#onDestroy()}).</p>
-     *
-     * @param token IME token to be removed.
-     * @hide
-     */
-    public void unregisterInputMethodPrivOps(IBinder token) {
-        mPrivOpsRegistry.remove(token);
-    }
 }
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 29339e9..3e240cf 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -44,6 +44,8 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 
+import com.google.android.textclassifier.AnnotatorModel;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -92,7 +94,7 @@
     @GuardedBy("mLock") // Do not access outside this lock.
     private ModelFile mModel;
     @GuardedBy("mLock") // Do not access outside this lock.
-    private TextClassifierImplNative mNative;
+    private AnnotatorModel mNative;
 
     private final Object mLoggerLock = new Object();
     @GuardedBy("mLoggerLock") // Do not access outside this lock.
@@ -125,7 +127,7 @@
                     && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
                 final String localesString = concatenateLocales(request.getDefaultLocales());
                 final ZonedDateTime refTime = ZonedDateTime.now();
-                final TextClassifierImplNative nativeImpl = getNative(request.getDefaultLocales());
+                final AnnotatorModel nativeImpl = getNative(request.getDefaultLocales());
                 final int start;
                 final int end;
                 if (mSettings.isModelDarkLaunchEnabled() && !request.isDarkLaunchAllowed()) {
@@ -134,7 +136,7 @@
                 } else {
                     final int[] startEnd = nativeImpl.suggestSelection(
                             string, request.getStartIndex(), request.getEndIndex(),
-                            new TextClassifierImplNative.SelectionOptions(localesString));
+                            new AnnotatorModel.SelectionOptions(localesString));
                     start = startEnd[0];
                     end = startEnd[1];
                 }
@@ -142,10 +144,10 @@
                         && start >= 0 && end <= string.length()
                         && start <= request.getStartIndex() && end >= request.getEndIndex()) {
                     final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
-                    final TextClassifierImplNative.ClassificationResult[] results =
+                    final AnnotatorModel.ClassificationResult[] results =
                             nativeImpl.classifyText(
                                     string, start, end,
-                                    new TextClassifierImplNative.ClassificationOptions(
+                                    new AnnotatorModel.ClassificationOptions(
                                             refTime.toInstant().toEpochMilli(),
                                             refTime.getZone().getId(),
                                             localesString));
@@ -184,11 +186,11 @@
                 final String localesString = concatenateLocales(request.getDefaultLocales());
                 final ZonedDateTime refTime = request.getReferenceTime() != null
                         ? request.getReferenceTime() : ZonedDateTime.now();
-                final TextClassifierImplNative.ClassificationResult[] results =
+                final AnnotatorModel.ClassificationResult[] results =
                         getNative(request.getDefaultLocales())
                                 .classifyText(
                                         string, request.getStartIndex(), request.getEndIndex(),
-                                        new TextClassifierImplNative.ClassificationOptions(
+                                        new AnnotatorModel.ClassificationOptions(
                                                 refTime.toInstant().toEpochMilli(),
                                                 refTime.getZone().getId(),
                                                 localesString));
@@ -228,17 +230,17 @@
                     ? request.getEntityConfig().resolveEntityListModifications(
                             getEntitiesForHints(request.getEntityConfig().getHints()))
                     : mSettings.getEntityListDefault();
-            final TextClassifierImplNative nativeImpl =
+            final AnnotatorModel nativeImpl =
                     getNative(request.getDefaultLocales());
-            final TextClassifierImplNative.AnnotatedSpan[] annotations =
+            final AnnotatorModel.AnnotatedSpan[] annotations =
                     nativeImpl.annotate(
                         textString,
-                        new TextClassifierImplNative.AnnotationOptions(
+                        new AnnotatorModel.AnnotationOptions(
                                 refTime.toInstant().toEpochMilli(),
                                         refTime.getZone().getId(),
                                 concatenateLocales(request.getDefaultLocales())));
-            for (TextClassifierImplNative.AnnotatedSpan span : annotations) {
-                final TextClassifierImplNative.ClassificationResult[] results =
+            for (AnnotatorModel.AnnotatedSpan span : annotations) {
+                final AnnotatorModel.ClassificationResult[] results =
                         span.getClassification();
                 if (results.length == 0
                         || !entitiesToIdentify.contains(results[0].getCollection())) {
@@ -297,7 +299,7 @@
         }
     }
 
-    private TextClassifierImplNative getNative(LocaleList localeList)
+    private AnnotatorModel getNative(LocaleList localeList)
             throws FileNotFoundException {
         synchronized (mLock) {
             localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
@@ -310,7 +312,7 @@
                 destroyNativeIfExistsLocked();
                 final ParcelFileDescriptor fd = ParcelFileDescriptor.open(
                         new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
-                mNative = new TextClassifierImplNative(fd.getFd());
+                mNative = new AnnotatorModel(fd.getFd());
                 closeAndLogError(fd);
                 mModel = bestModel;
             }
@@ -398,14 +400,14 @@
     }
 
     private TextClassification createClassificationResult(
-            TextClassifierImplNative.ClassificationResult[] classifications,
+            AnnotatorModel.ClassificationResult[] classifications,
             String text, int start, int end, @Nullable Instant referenceTime) {
         final String classifiedText = text.substring(start, end);
         final TextClassification.Builder builder = new TextClassification.Builder()
                 .setText(classifiedText);
 
         final int size = classifications.length;
-        TextClassifierImplNative.ClassificationResult highestScoringResult = null;
+        AnnotatorModel.ClassificationResult highestScoringResult = null;
         float highestScore = Float.MIN_VALUE;
         for (int i = 0; i < size; i++) {
             builder.setEntityType(classifications[i].getCollection(),
@@ -486,9 +488,9 @@
             try {
                 final ParcelFileDescriptor modelFd = ParcelFileDescriptor.open(
                         file, ParcelFileDescriptor.MODE_READ_ONLY);
-                final int version = TextClassifierImplNative.getVersion(modelFd.getFd());
+                final int version = AnnotatorModel.getVersion(modelFd.getFd());
                 final String supportedLocalesStr =
-                        TextClassifierImplNative.getLocales(modelFd.getFd());
+                        AnnotatorModel.getLocales(modelFd.getFd());
                 if (supportedLocalesStr.isEmpty()) {
                     Log.d(DEFAULT_LOG_TAG, "Ignoring " + file.getAbsolutePath());
                     return null;
@@ -676,7 +678,7 @@
         public static List<LabeledIntent> create(
                 Context context,
                 @Nullable Instant referenceTime,
-                TextClassifierImplNative.ClassificationResult classification,
+                AnnotatorModel.ClassificationResult classification,
                 String text) {
             final String type = classification.getCollection().trim().toLowerCase(Locale.ENGLISH);
             text = text.trim();
diff --git a/core/java/android/view/textclassifier/TextClassifierImplNative.java b/core/java/android/view/textclassifier/TextClassifierImplNative.java
deleted file mode 100644
index 3d4c8f2..0000000
--- a/core/java/android/view/textclassifier/TextClassifierImplNative.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.textclassifier;
-
-import android.content.res.AssetFileDescriptor;
-
-/**
- * Java wrapper for TextClassifier native library interface. This library is used for detecting
- * entities in text.
- */
-final class TextClassifierImplNative {
-
-    static {
-        System.loadLibrary("textclassifier");
-    }
-
-    private final long mModelPtr;
-
-    /**
-     * Creates a new instance of TextClassifierImplNative, using the provided model image, given as
-     * a file descriptor.
-     */
-    TextClassifierImplNative(int fd) {
-        mModelPtr = nativeNew(fd);
-        if (mModelPtr == 0L) {
-            throw new IllegalArgumentException("Couldn't initialize TC from file descriptor.");
-        }
-    }
-
-    /**
-     * Creates a new instance of TextClassifierImplNative, using the provided model image, given as
-     * a file path.
-     */
-    TextClassifierImplNative(String path) {
-        mModelPtr = nativeNewFromPath(path);
-        if (mModelPtr == 0L) {
-            throw new IllegalArgumentException("Couldn't initialize TC from given file.");
-        }
-    }
-
-    /**
-     * Creates a new instance of TextClassifierImplNative, using the provided model image, given as
-     * an AssetFileDescriptor.
-     */
-    TextClassifierImplNative(AssetFileDescriptor afd) {
-        mModelPtr = nativeNewFromAssetFileDescriptor(afd, afd.getStartOffset(), afd.getLength());
-        if (mModelPtr == 0L) {
-            throw new IllegalArgumentException(
-                    "Couldn't initialize TC from given AssetFileDescriptor");
-        }
-    }
-
-    /**
-     * Given a string context and current selection, computes the SmartSelection suggestion.
-     *
-     * <p>The begin and end are character indices into the context UTF8 string. selectionBegin is
-     * the character index where the selection begins, and selectionEnd is the index of one
-     * character past the selection span.
-     *
-     * <p>The return value is an array of two ints: suggested selection beginning and end, with the
-     * same semantics as the input selectionBeginning and selectionEnd.
-     */
-    public int[] suggestSelection(
-            String context, int selectionBegin, int selectionEnd, SelectionOptions options) {
-        return nativeSuggestSelection(mModelPtr, context, selectionBegin, selectionEnd, options);
-    }
-
-    /**
-     * Given a string context and current selection, classifies the type of the selected text.
-     *
-     * <p>The begin and end params are character indices in the context string.
-     *
-     * <p>Returns an array of ClassificationResult objects with the probability scores for different
-     * collections.
-     */
-    public ClassificationResult[] classifyText(
-            String context, int selectionBegin, int selectionEnd, ClassificationOptions options) {
-        return nativeClassifyText(mModelPtr, context, selectionBegin, selectionEnd, options);
-    }
-
-    /**
-     * Annotates given input text. The annotations should cover the whole input context except for
-     * whitespaces, and are sorted by their position in the context string.
-     */
-    public AnnotatedSpan[] annotate(String text, AnnotationOptions options) {
-        return nativeAnnotate(mModelPtr, text, options);
-    }
-
-    /** Frees up the allocated memory. */
-    public void close() {
-        nativeClose(mModelPtr);
-    }
-
-    /** Returns a comma separated list of locales supported by the model as BCP 47 tags. */
-    public static String getLocales(int fd) {
-        return nativeGetLocales(fd);
-    }
-
-    /** Returns the version of the model. */
-    public static int getVersion(int fd) {
-        return nativeGetVersion(fd);
-    }
-
-    /** Represents a datetime parsing result from classifyText calls. */
-    public static final class DatetimeResult {
-        static final int GRANULARITY_YEAR = 0;
-        static final int GRANULARITY_MONTH = 1;
-        static final int GRANULARITY_WEEK = 2;
-        static final int GRANULARITY_DAY = 3;
-        static final int GRANULARITY_HOUR = 4;
-        static final int GRANULARITY_MINUTE = 5;
-        static final int GRANULARITY_SECOND = 6;
-
-        private final long mTimeMsUtc;
-        private final int mGranularity;
-
-        DatetimeResult(long timeMsUtc, int granularity) {
-            mGranularity = granularity;
-            mTimeMsUtc = timeMsUtc;
-        }
-
-        public long getTimeMsUtc() {
-            return mTimeMsUtc;
-        }
-
-        public int getGranularity() {
-            return mGranularity;
-        }
-    }
-
-    /** Represents a result of classifyText method call. */
-    public static final class ClassificationResult {
-        private final String mCollection;
-        private final float mScore;
-        private final DatetimeResult mDatetimeResult;
-
-        ClassificationResult(
-                String collection, float score, DatetimeResult datetimeResult) {
-            mCollection = collection;
-            mScore = score;
-            mDatetimeResult = datetimeResult;
-        }
-
-        public String getCollection() {
-            if (mCollection.equals(TextClassifier.TYPE_DATE) && mDatetimeResult != null) {
-                switch (mDatetimeResult.getGranularity()) {
-                    case DatetimeResult.GRANULARITY_HOUR:
-                        // fall through
-                    case DatetimeResult.GRANULARITY_MINUTE:
-                        // fall through
-                    case DatetimeResult.GRANULARITY_SECOND:
-                        return TextClassifier.TYPE_DATE_TIME;
-                    default:
-                        return TextClassifier.TYPE_DATE;
-                }
-            }
-            return mCollection;
-        }
-
-        public float getScore() {
-            return mScore;
-        }
-
-        public DatetimeResult getDatetimeResult() {
-            return mDatetimeResult;
-        }
-    }
-
-    /** Represents a result of Annotate call. */
-    public static final class AnnotatedSpan {
-        private final int mStartIndex;
-        private final int mEndIndex;
-        private final ClassificationResult[] mClassification;
-
-        AnnotatedSpan(
-                int startIndex, int endIndex, ClassificationResult[] classification) {
-            mStartIndex = startIndex;
-            mEndIndex = endIndex;
-            mClassification = classification;
-        }
-
-        public int getStartIndex() {
-            return mStartIndex;
-        }
-
-        public int getEndIndex() {
-            return mEndIndex;
-        }
-
-        public ClassificationResult[] getClassification() {
-            return mClassification;
-        }
-    }
-
-    /** Represents options for the suggestSelection call. */
-    public static final class SelectionOptions {
-        private final String mLocales;
-
-        SelectionOptions(String locales) {
-            mLocales = locales;
-        }
-
-        public String getLocales() {
-            return mLocales;
-        }
-    }
-
-    /** Represents options for the classifyText call. */
-    public static final class ClassificationOptions {
-        private final long mReferenceTimeMsUtc;
-        private final String mReferenceTimezone;
-        private final String mLocales;
-
-        ClassificationOptions(long referenceTimeMsUtc, String referenceTimezone, String locale) {
-            mReferenceTimeMsUtc = referenceTimeMsUtc;
-            mReferenceTimezone = referenceTimezone;
-            mLocales = locale;
-        }
-
-        public long getReferenceTimeMsUtc() {
-            return mReferenceTimeMsUtc;
-        }
-
-        public String getReferenceTimezone() {
-            return mReferenceTimezone;
-        }
-
-        public String getLocale() {
-            return mLocales;
-        }
-    }
-
-    /** Represents options for the Annotate call. */
-    public static final class AnnotationOptions {
-        private final long mReferenceTimeMsUtc;
-        private final String mReferenceTimezone;
-        private final String mLocales;
-
-        AnnotationOptions(long referenceTimeMsUtc, String referenceTimezone, String locale) {
-            mReferenceTimeMsUtc = referenceTimeMsUtc;
-            mReferenceTimezone = referenceTimezone;
-            mLocales = locale;
-        }
-
-        public long getReferenceTimeMsUtc() {
-            return mReferenceTimeMsUtc;
-        }
-
-        public String getReferenceTimezone() {
-            return mReferenceTimezone;
-        }
-
-        public String getLocale() {
-            return mLocales;
-        }
-    }
-
-    private static native long nativeNew(int fd);
-
-    private static native long nativeNewFromPath(String path);
-
-    private static native long nativeNewFromAssetFileDescriptor(
-            AssetFileDescriptor afd, long offset, long size);
-
-    private static native int[] nativeSuggestSelection(
-            long context,
-            String text,
-            int selectionBegin,
-            int selectionEnd,
-            SelectionOptions options);
-
-    private static native ClassificationResult[] nativeClassifyText(
-            long context,
-            String text,
-            int selectionBegin,
-            int selectionEnd,
-            ClassificationOptions options);
-
-    private static native AnnotatedSpan[] nativeAnnotate(
-            long context, String text, AnnotationOptions options);
-
-    private static native void nativeClose(long context);
-
-    private static native String nativeGetLocales(int fd);
-
-    private static native int nativeGetVersion(int fd);
-}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index ae6a2fd..23d1237 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -25,6 +25,13 @@
  * Cookies are manipulated according to RFC2109.
  */
 public abstract class CookieManager {
+    /**
+     * @deprecated This class should not be constructed by applications, use {@link #getInstance}
+     * instead to fetch the singleton instance.
+     */
+    // TODO(ntfschr): mark this as @SystemApi after a year.
+    @Deprecated
+    public CookieManager() {}
 
     @Override
     protected Object clone() throws CloneNotSupportedException {
diff --git a/core/java/android/webkit/RenderProcessGoneDetail.java b/core/java/android/webkit/RenderProcessGoneDetail.java
index 0843e26..9beeaa5 100644
--- a/core/java/android/webkit/RenderProcessGoneDetail.java
+++ b/core/java/android/webkit/RenderProcessGoneDetail.java
@@ -22,6 +22,13 @@
  **/
 public abstract class RenderProcessGoneDetail {
     /**
+     * @deprecated This class should not be constructed by applications.
+     */
+    // TODO(ntfschr): mark this as @SystemApi after a year.
+    @Deprecated
+    public RenderProcessGoneDetail() {}
+
+    /**
      * Indicates whether the render process was observed to crash, or whether
      * it was killed by the system.
      *
diff --git a/core/java/android/webkit/SafeBrowsingResponse.java b/core/java/android/webkit/SafeBrowsingResponse.java
index 7839a00..ca33a0c 100644
--- a/core/java/android/webkit/SafeBrowsingResponse.java
+++ b/core/java/android/webkit/SafeBrowsingResponse.java
@@ -27,6 +27,12 @@
  * {@link android.webkit.WebView#getSafeBrowsingPrivacyPolicyUrl()}.
  */
 public abstract class SafeBrowsingResponse {
+    /**
+     * @deprecated This class should not be constructed by applications.
+     */
+    // TODO(ntfschr): mark this as @SystemApi after a year.
+    @Deprecated
+    public SafeBrowsingResponse() {}
 
     /**
      * Display the default interstitial.
diff --git a/core/java/android/webkit/ServiceWorkerController.java b/core/java/android/webkit/ServiceWorkerController.java
index 3517c74..d7e0715 100644
--- a/core/java/android/webkit/ServiceWorkerController.java
+++ b/core/java/android/webkit/ServiceWorkerController.java
@@ -38,6 +38,14 @@
 public abstract class ServiceWorkerController {
 
     /**
+     * @deprecated This class should not be constructed by applications, use {@link #getInstance()}
+     * instead to fetch the singleton instance.
+     */
+    // TODO(ntfschr): mark this as @SystemApi after a year.
+    @Deprecated
+    public ServiceWorkerController() {}
+
+    /**
      * Returns the default ServiceWorkerController instance. At present there is
      * only one ServiceWorkerController instance for all WebView instances,
      * however this restriction may be relaxed in the future.
diff --git a/core/java/android/webkit/TracingController.java b/core/java/android/webkit/TracingController.java
index 05c0304..9908182 100644
--- a/core/java/android/webkit/TracingController.java
+++ b/core/java/android/webkit/TracingController.java
@@ -36,13 +36,20 @@
  * <pre class="prettyprint">
  * TracingController tracingController = TracingController.getInstance();
  * tracingController.start(new TracingConfig.Builder()
- *                  .addCategories(CATEGORIES_WEB_DEVELOPER).build());
+ *                  .addCategories(TracingConfig.CATEGORIES_WEB_DEVELOPER).build());
  * ...
  * tracingController.stop(new FileOutputStream("trace.json"),
  *                        Executors.newSingleThreadExecutor());
  * </pre></p>
  */
 public abstract class TracingController {
+    /**
+     * @deprecated This class should not be constructed by applications, use {@link #getInstance}
+     * instead to fetch the singleton instance.
+     */
+    // TODO(ntfschr): mark this as @SystemApi after a year.
+    @Deprecated
+    public TracingController() {}
 
     /**
      * Returns the default TracingController instance. At present there is
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index f6166c5..f346c60 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -31,6 +31,14 @@
  */
 public abstract class WebViewDatabase {
     /**
+     * @deprecated This class should not be constructed by applications, use {@link
+     * #getInstance(Context)} instead to fetch the singleton instance.
+     */
+    // TODO(ntfschr): mark this as @SystemApi after a year.
+    @Deprecated
+    public WebViewDatabase() {}
+
+    /**
      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
      */
     protected static final String LOGTAG = "webviewdatabase";
diff --git a/core/java/android/widget/DigitalClock.java b/core/java/android/widget/DigitalClock.java
index c503ef2..8ebf303 100644
--- a/core/java/android/widget/DigitalClock.java
+++ b/core/java/android/widget/DigitalClock.java
@@ -27,7 +27,7 @@
 import java.util.Calendar;
 
 /**
- * Like AnalogClock, but digital.  Shows seconds.
+ * Like AnalogClock, but digital.
  *
  * @deprecated It is recommended you use {@link TextClock} instead.
  */
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 8dd30f6..8027dd7 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -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;
@@ -388,7 +389,8 @@
                 com.android.internal.R.bool.config_enableHapticTextHandle);
 
         if (FLAG_USE_MAGNIFIER) {
-            mMagnifierAnimator = new MagnifierMotionAnimator(new Magnifier(mTextView));
+            final Magnifier magnifier = new Magnifier.Builder(mTextView).build();
+            mMagnifierAnimator = new MagnifierMotionAnimator(magnifier);
         }
     }
 
@@ -4799,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
@@ -4927,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/ImageView.java b/core/java/android/widget/ImageView.java
index 0fef9a5..12cc54d 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -1338,7 +1338,9 @@
             return;
         }
         if (matrix == null) {
-            mDrawable.setBounds(0, 0, getWidth(), getHeight());
+            final int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
+            final int vheight = getHeight() - mPaddingTop - mPaddingBottom;
+            mDrawable.setBounds(0, 0, vwidth, vheight);
         } else {
             mDrawable.setBounds(0, 0, mDrawableWidth, mDrawableHeight);
             if (mDrawMatrix == null) {
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 8e2786d..16ddd0f 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -119,8 +119,9 @@
      *
      * @param view the view for which this magnifier is attached
      *
-     * @see Builder
+     * @deprecated Please use {@link Builder} instead
      */
+    @Deprecated
     public Magnifier(@NonNull View view) {
         this(new Builder(view));
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index dfbaf9a..9d06680 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -321,6 +321,12 @@
  * @attr ref android.R.styleable#TextView_autoSizeMaxTextSize
  * @attr ref android.R.styleable#TextView_autoSizeStepGranularity
  * @attr ref android.R.styleable#TextView_autoSizePresetSizes
+ * @attr ref android.R.styleable#TextView_textCursorDrawable
+ * @attr ref android.R.styleable#TextView_textSelectHandle
+ * @attr ref android.R.styleable#TextView_textSelectHandleLeft
+ * @attr ref android.R.styleable#TextView_textSelectHandleRight
+ * @attr ref android.R.styleable#TextView_allowUndo
+ * @attr ref android.R.styleable#TextView_enabled
  */
 @RemoteView
 public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -876,9 +882,6 @@
     private boolean mTextSetFromXmlOrResourceId = false;
     // Resource id used to set the text.
     private @StringRes int mTextId = ResourceId.ID_NULL;
-    // Last value used on AFM.notifyValueChanged(), used to optimize autofill workflow by avoiding
-    // calls when the value did not change
-    private CharSequence mLastValueSentToAutofillManager;
     //
     // End of autofill-related attributes
 
@@ -5878,7 +5881,7 @@
         if (needEditableForNotification) {
             sendAfterTextChanged((Editable) text);
         } else {
-            notifyAutoFillManagerAfterTextChangedIfNeeded();
+            notifyAutoFillManagerAfterTextChanged();
         }
 
         // SelectionModifierCursorController depends on textCanBeSelected, which depends on text
@@ -9927,33 +9930,23 @@
         }
 
         // Always notify AutoFillManager - it will return right away if autofill is disabled.
-        notifyAutoFillManagerAfterTextChangedIfNeeded();
+        notifyAutoFillManagerAfterTextChanged();
 
         hideErrorIfUnchanged();
     }
 
-    private void notifyAutoFillManagerAfterTextChangedIfNeeded() {
+    private void notifyAutoFillManagerAfterTextChanged() {
         // It is important to not check whether the view is important for autofill
         // since the user can trigger autofill manually on not important views.
         if (!isAutofillable()) {
             return;
         }
         final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
-        if (afm == null) {
-            return;
-        }
-
-        if (mLastValueSentToAutofillManager == null
-                || !mLastValueSentToAutofillManager.equals(mText)) {
+        if (afm != null) {
             if (android.view.autofill.Helper.sVerbose) {
-                Log.v(LOG_TAG, "notifying AFM after text changed");
+                Log.v(LOG_TAG, "notifyAutoFillManagerAfterTextChanged");
             }
             afm.notifyValueChanged(TextView.this);
-            mLastValueSentToAutofillManager = mText;
-        } else {
-            if (android.view.autofill.Helper.sVerbose) {
-                Log.v(LOG_TAG, "not notifying AFM on unchanged text");
-            }
         }
     }
 
@@ -12495,11 +12488,11 @@
                     advancesIndex);
         }
 
-        public int getTextRunCursor(int contextStart, int contextEnd, int dir,
+        public int getTextRunCursor(int contextStart, int contextEnd, boolean isRtl,
                 int offset, int cursorOpt, Paint p) {
             int contextCount = contextEnd - contextStart;
             return p.getTextRunCursor(mChars, contextStart + mStart,
-                    contextCount, dir, offset + mStart, cursorOpt);
+                    contextCount, isRtl, offset + mStart, cursorOpt);
         }
     }
 
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 9171959..0f8295a 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -16,8 +16,7 @@
 
 package com.android.internal.app;
 
-import com.android.internal.R;
-
+import android.annotation.NonNull;
 import android.app.SearchManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,6 +31,9 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.Set;
+
 /**
  * Utility method for dealing with the assistant aspects of
  * {@link com.android.internal.app.IVoiceInteractionManagerService IVoiceInteractionManagerService}.
@@ -62,6 +64,30 @@
         return false;
     }
 
+    /**
+     * Checks the availability of a set of voice actions for the current active voice service.
+     *
+     * @param voiceActions A set of supported voice actions to be checked.
+     * @param callback     The callback which will deliver a set of supported voice actions. If
+     *                     no voice actions are supported for the given voice action set, then null
+     *                     or empty set is provided.
+     */
+    public void getActiveServiceSupportedActions(@NonNull Set<String> voiceActions,
+            @NonNull IVoiceActionCheckCallback callback) {
+        try {
+            if (mVoiceInteractionManagerService != null) {
+                mVoiceInteractionManagerService
+                        .getActiveServiceSupportedActions(new ArrayList<>(voiceActions), callback);
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to call activeServiceSupportedActions", e);
+            try {
+                callback.onComplete(null);
+            } catch (RemoteException re) {
+            }
+        }
+    }
+
     public void launchVoiceAssistFromKeyguard() {
         try {
             if (mVoiceInteractionManagerService != null) {
@@ -157,7 +183,7 @@
             return getActiveServiceComponentName();
         }
         final SearchManager searchManager =
-            (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+                (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
         if (searchManager == null) {
             return null;
         }
diff --git a/core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl b/core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl
new file mode 100644
index 0000000..66ba93d
--- /dev/null
+++ b/core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl
@@ -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.
+ */
+
+package com.android.internal.app;
+
+oneway interface IVoiceActionCheckCallback {
+    void onComplete(in List<String> voiceActions);
+}
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index ff75a8b..5088cca 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 
+import com.android.internal.app.IVoiceActionCheckCallback;
 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.IVoiceInteractionSessionListener;
@@ -143,4 +144,11 @@
      * Register a voice interaction listener.
      */
     void registerVoiceInteractionSessionListener(IVoiceInteractionSessionListener listener);
+
+    /**
+     * Checks the availability of a set of voice actions for the current active voice service.
+     * Returns all supported voice actions.
+     */
+    void getActiveServiceSupportedActions(in List<String> voiceActions,
+     in IVoiceActionCheckCallback callback);
 }
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/procstats/IProcessStats.aidl b/core/java/com/android/internal/app/procstats/IProcessStats.aidl
index 44867c7..0c203ab 100644
--- a/core/java/com/android/internal/app/procstats/IProcessStats.aidl
+++ b/core/java/com/android/internal/app/procstats/IProcessStats.aidl
@@ -24,4 +24,14 @@
     byte[] getCurrentStats(out List<ParcelFileDescriptor> historic);
     ParcelFileDescriptor getStatsOverTime(long minTime);
     int getCurrentMemoryState();
+
+    /**
+     * Get stats committed after highWaterMarkMs
+     * @param highWaterMarkMs Report stats committed after this time.
+     * @param section Integer mask to indicate which sections to include in the stats.
+     * @param doAggregate Whether to aggregate the stats or keep them separated.
+     * @param List of Files of individual commits in protobuf binary or one that is merged from them.
+     */
+     long getCommittedStats(long highWaterMarkMs, int section, boolean doAggregate,
+        out List<ParcelFileDescriptor> committedStats);
 }
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index f6e99ba..e7ac566 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -158,6 +158,25 @@
             STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
     };
 
+    // Should report process stats.
+    public static final int REPORT_PROC_STATS = 0x01;
+    // Should report package process stats.
+    public static final int REPORT_PKG_PROC_STATS = 0x02;
+    // Should report package service stats.
+    public static final int REPORT_PKG_SVC_STATS = 0x04;
+    // Should report package association stats.
+    public static final int REPORT_PKG_ASC_STATS = 0x08;
+    // Should report package stats.
+    public static final int REPORT_PKG_STATS = 0x0E;
+    // Should report all stats.
+    public static final int REPORT_ALL = 0x0F;
+
+    public static final int[] OPTIONS =
+            {REPORT_PROC_STATS, REPORT_PKG_PROC_STATS, REPORT_PKG_SVC_STATS, REPORT_PKG_ASC_STATS,
+                    REPORT_PKG_STATS, REPORT_ALL};
+    public static final String[] OPTIONS_STR =
+            {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"};
+
     // Current version of the parcel format.
     private static final int PARCEL_VERSION = 34;
     // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
@@ -1412,7 +1431,7 @@
     }
 
     public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
-            boolean dumpDetails, boolean dumpAll, boolean activeOnly) {
+            boolean dumpDetails, boolean dumpAll, boolean activeOnly, int section) {
         long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
                 mStartTime, now);
         boolean sepNeeded = false;
@@ -1421,176 +1440,205 @@
             mSysMemUsage.dump(pw, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
             sepNeeded = true;
         }
-        ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = mPackages.getMap();
         boolean printedHeader = false;
-        for (int ip=0; ip<pkgMap.size(); ip++) {
-            final String pkgName = pkgMap.keyAt(ip);
-            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
-            for (int iu=0; iu<uids.size(); iu++) {
-                final int uid = uids.keyAt(iu);
-                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
-                for (int iv=0; iv<vpkgs.size(); iv++) {
-                    final long vers = vpkgs.keyAt(iv);
-                    final PackageState pkgState = vpkgs.valueAt(iv);
-                    final int NPROCS = pkgState.mProcesses.size();
-                    final int NSRVS = pkgState.mServices.size();
-                    final int NASCS = pkgState.mAssociations.size();
-                    final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
-                    if (!pkgMatch) {
-                        boolean procMatch = false;
-                        for (int iproc=0; iproc<NPROCS; iproc++) {
-                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                            if (reqPackage.equals(proc.getName())) {
-                                procMatch = true;
-                                break;
+        if ((section & REPORT_PKG_STATS) != 0) {
+            ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
+                    mPackages.getMap();
+            for (int ip = 0; ip < pkgMap.size(); ip++) {
+                final String pkgName = pkgMap.keyAt(ip);
+                final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+                for (int iu = 0; iu < uids.size(); iu++) {
+                    final int uid = uids.keyAt(iu);
+                    final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                    for (int iv = 0; iv < vpkgs.size(); iv++) {
+                        final long vers = vpkgs.keyAt(iv);
+                        final PackageState pkgState = vpkgs.valueAt(iv);
+                        final int NPROCS = pkgState.mProcesses.size();
+                        final int NSRVS = pkgState.mServices.size();
+                        final int NASCS = pkgState.mAssociations.size();
+                        final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+                        if (!pkgMatch) {
+                            boolean procMatch = false;
+                            for (int iproc = 0; iproc < NPROCS; iproc++) {
+                                ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                                if (reqPackage.equals(proc.getName())) {
+                                    procMatch = true;
+                                    break;
+                                }
                             }
-                        }
-                        if (!procMatch) {
-                            continue;
-                        }
-                    }
-                    if (NPROCS > 0 || NSRVS > 0 || NASCS > 0) {
-                        if (!printedHeader) {
-                            if (sepNeeded) pw.println();
-                            pw.println("Per-Package Stats:");
-                            printedHeader = true;
-                            sepNeeded = true;
-                        }
-                        pw.print("  * "); pw.print(pkgName); pw.print(" / ");
-                                UserHandle.formatUid(pw, uid); pw.print(" / v");
-                                pw.print(vers); pw.println(":");
-                    }
-                    if (!dumpSummary || dumpAll) {
-                        for (int iproc=0; iproc<NPROCS; iproc++) {
-                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                            if (!pkgMatch && !reqPackage.equals(proc.getName())) {
+                            if (!procMatch) {
                                 continue;
                             }
-                            if (activeOnly && !proc.isInUse()) {
-                                pw.print("      (Not active: ");
-                                        pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
-                                continue;
+                        }
+                        if (NPROCS > 0 || NSRVS > 0 || NASCS > 0) {
+                            if (!printedHeader) {
+                                if (sepNeeded) pw.println();
+                                pw.println("Per-Package Stats:");
+                                printedHeader = true;
+                                sepNeeded = true;
                             }
-                            pw.print("      Process ");
-                            pw.print(pkgState.mProcesses.keyAt(iproc));
-                            if (proc.getCommonProcess().isMultiPackage()) {
-                                pw.print(" (multi, ");
-                            } else {
-                                pw.print(" (unique, ");
-                            }
-                            pw.print(proc.getDurationsBucketCount());
-                            pw.print(" entries)");
+                            pw.print("  * ");
+                            pw.print(pkgName);
+                            pw.print(" / ");
+                            UserHandle.formatUid(pw, uid);
+                            pw.print(" / v");
+                            pw.print(vers);
                             pw.println(":");
-                            proc.dumpProcessState(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
-                                    ALL_PROC_STATES, now);
-                            proc.dumpPss(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
-                                    ALL_PROC_STATES, now);
-                            proc.dumpInternalLocked(pw, "        ", dumpAll);
                         }
-                    } else {
-                        ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
-                        for (int iproc=0; iproc<NPROCS; iproc++) {
-                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                            if (!pkgMatch && !reqPackage.equals(proc.getName())) {
-                                continue;
+                        if ((section & REPORT_PKG_PROC_STATS) != 0) {
+                            if (!dumpSummary || dumpAll) {
+                                for (int iproc = 0; iproc < NPROCS; iproc++) {
+                                    ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                                    if (!pkgMatch && !reqPackage.equals(proc.getName())) {
+                                        continue;
+                                    }
+                                    if (activeOnly && !proc.isInUse()) {
+                                        pw.print("      (Not active: ");
+                                        pw.print(pkgState.mProcesses.keyAt(iproc));
+                                        pw.println(")");
+                                        continue;
+                                    }
+                                    pw.print("      Process ");
+                                    pw.print(pkgState.mProcesses.keyAt(iproc));
+                                    if (proc.getCommonProcess().isMultiPackage()) {
+                                        pw.print(" (multi, ");
+                                    } else {
+                                        pw.print(" (unique, ");
+                                    }
+                                    pw.print(proc.getDurationsBucketCount());
+                                    pw.print(" entries)");
+                                    pw.println(":");
+                                    proc.dumpProcessState(pw, "        ", ALL_SCREEN_ADJ,
+                                            ALL_MEM_ADJ,
+                                            ALL_PROC_STATES, now);
+                                    proc.dumpPss(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                            ALL_PROC_STATES, now);
+                                    proc.dumpInternalLocked(pw, "        ", dumpAll);
+                                }
+                            } else {
+                                ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
+                                for (int iproc = 0; iproc < NPROCS; iproc++) {
+                                    ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                                    if (!pkgMatch && !reqPackage.equals(proc.getName())) {
+                                        continue;
+                                    }
+                                    if (activeOnly && !proc.isInUse()) {
+                                        continue;
+                                    }
+                                    procs.add(proc);
+                                }
+                                DumpUtils.dumpProcessSummaryLocked(pw, "      ", "Prc ", procs,
+                                        ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES,
+                                        now, totalTime);
                             }
-                            if (activeOnly && !proc.isInUse()) {
-                                continue;
+                        }
+                        if ((section & REPORT_PKG_SVC_STATS) != 0) {
+                            for (int isvc = 0; isvc < NSRVS; isvc++) {
+                                ServiceState svc = pkgState.mServices.valueAt(isvc);
+                                if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) {
+                                    continue;
+                                }
+                                if (activeOnly && !svc.isInUse()) {
+                                    pw.print("      (Not active service: ");
+                                    pw.print(pkgState.mServices.keyAt(isvc));
+                                    pw.println(")");
+                                    continue;
+                                }
+                                if (dumpAll) {
+                                    pw.print("      Service ");
+                                } else {
+                                    pw.print("      * Svc ");
+                                }
+                                pw.print(pkgState.mServices.keyAt(isvc));
+                                pw.println(":");
+                                pw.print("        Process: ");
+                                pw.println(svc.getProcessName());
+                                svc.dumpStats(pw, "        ", "          ", "    ",
+                                        now, totalTime, dumpSummary, dumpAll);
                             }
-                            procs.add(proc);
                         }
-                        DumpUtils.dumpProcessSummaryLocked(pw, "      ", "Prc ", procs,
-                                ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES,
-                                now, totalTime);
-                    }
-                    for (int isvc=0; isvc<NSRVS; isvc++) {
-                        ServiceState svc = pkgState.mServices.valueAt(isvc);
-                        if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) {
-                            continue;
+                        if ((section & REPORT_PKG_ASC_STATS) != 0) {
+                            for (int iasc = 0; iasc < NASCS; iasc++) {
+                                AssociationState asc = pkgState.mAssociations.valueAt(iasc);
+                                if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) {
+                                    continue;
+                                }
+                                if (activeOnly && !asc.isInUse()) {
+                                    pw.print("      (Not active association: ");
+                                    pw.print(pkgState.mAssociations.keyAt(iasc));
+                                    pw.println(")");
+                                    continue;
+                                }
+                                if (dumpAll) {
+                                    pw.print("      Association ");
+                                } else {
+                                    pw.print("      * Asc ");
+                                }
+                                pw.print(pkgState.mAssociations.keyAt(iasc));
+                                pw.println(":");
+                                pw.print("        Process: ");
+                                pw.println(asc.getProcessName());
+                                asc.dumpStats(pw, "        ", "          ", "    ",
+                                        now, totalTime, dumpDetails, dumpAll);
+                            }
                         }
-                        if (activeOnly && !svc.isInUse()) {
-                            pw.print("      (Not active service: ");
-                                    pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
-                            continue;
-                        }
-                        if (dumpAll) {
-                            pw.print("      Service ");
-                        } else {
-                            pw.print("      * Svc ");
-                        }
-                        pw.print(pkgState.mServices.keyAt(isvc));
-                        pw.println(":");
-                        pw.print("        Process: "); pw.println(svc.getProcessName());
-                        svc.dumpStats(pw, "        ", "          ", "    ",
-                                now, totalTime, dumpSummary, dumpAll);
-                    }
-                    for (int iasc=0; iasc<NASCS; iasc++) {
-                        AssociationState asc = pkgState.mAssociations.valueAt(iasc);
-                        if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) {
-                            continue;
-                        }
-                        if (activeOnly && !asc.isInUse()) {
-                            pw.print("      (Not active association: ");
-                            pw.print(pkgState.mAssociations.keyAt(iasc)); pw.println(")");
-                            continue;
-                        }
-                        if (dumpAll) {
-                            pw.print("      Association ");
-                        } else {
-                            pw.print("      * Asc ");
-                        }
-                        pw.print(pkgState.mAssociations.keyAt(iasc));
-                        pw.println(":");
-                        pw.print("        Process: "); pw.println(asc.getProcessName());
-                        asc.dumpStats(pw, "        ", "          ", "    ",
-                                now, totalTime, dumpDetails, dumpAll);
                     }
                 }
             }
         }
 
-        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
-        printedHeader = false;
-        int numShownProcs = 0, numTotalProcs = 0;
-        for (int ip=0; ip<procMap.size(); ip++) {
-            String procName = procMap.keyAt(ip);
-            SparseArray<ProcessState> uids = procMap.valueAt(ip);
-            for (int iu=0; iu<uids.size(); iu++) {
-                int uid = uids.keyAt(iu);
-                numTotalProcs++;
-                final ProcessState proc = uids.valueAt(iu);
-                if (!proc.hasAnyData()) {
-                    continue;
+        if ((section & REPORT_PROC_STATS) != 0) {
+            ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+            printedHeader = false;
+            int numShownProcs = 0, numTotalProcs = 0;
+            for (int ip = 0; ip < procMap.size(); ip++) {
+                String procName = procMap.keyAt(ip);
+                SparseArray<ProcessState> uids = procMap.valueAt(ip);
+                for (int iu = 0; iu < uids.size(); iu++) {
+                    int uid = uids.keyAt(iu);
+                    numTotalProcs++;
+                    final ProcessState proc = uids.valueAt(iu);
+                    if (!proc.hasAnyData()) {
+                        continue;
+                    }
+                    if (!proc.isMultiPackage()) {
+                        continue;
+                    }
+                    if (reqPackage != null && !reqPackage.equals(procName)
+                            && !reqPackage.equals(proc.getPackage())) {
+                        continue;
+                    }
+                    numShownProcs++;
+                    if (sepNeeded) {
+                        pw.println();
+                    }
+                    sepNeeded = true;
+                    if (!printedHeader) {
+                        pw.println("Multi-Package Common Processes:");
+                        printedHeader = true;
+                    }
+                    if (activeOnly && !proc.isInUse()) {
+                        pw.print("      (Not active: ");
+                        pw.print(procName);
+                        pw.println(")");
+                        continue;
+                    }
+                    pw.print("  * ");
+                    pw.print(procName);
+                    pw.print(" / ");
+                    UserHandle.formatUid(pw, uid);
+                    pw.print(" (");
+                    pw.print(proc.getDurationsBucketCount());
+                    pw.print(" entries)");
+                    pw.println(":");
+                    proc.dumpProcessState(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                            ALL_PROC_STATES, now);
+                    proc.dumpPss(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now);
+                    proc.dumpInternalLocked(pw, "        ", dumpAll);
                 }
-                if (!proc.isMultiPackage()) {
-                    continue;
-                }
-                if (reqPackage != null && !reqPackage.equals(procName)
-                        && !reqPackage.equals(proc.getPackage())) {
-                    continue;
-                }
-                numShownProcs++;
-                if (sepNeeded) {
-                    pw.println();
-                }
-                sepNeeded = true;
-                if (!printedHeader) {
-                    pw.println("Multi-Package Common Processes:");
-                    printedHeader = true;
-                }
-                if (activeOnly && !proc.isInUse()) {
-                    pw.print("      (Not active: "); pw.print(procName); pw.println(")");
-                    continue;
-                }
-                pw.print("  * "); pw.print(procName); pw.print(" / ");
-                        UserHandle.formatUid(pw, uid);
-                        pw.print(" ("); pw.print(proc.getDurationsBucketCount());
-                        pw.print(" entries)"); pw.println(":");
-                proc.dumpProcessState(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
-                        ALL_PROC_STATES, now);
-                proc.dumpPss(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now);
-                proc.dumpInternalLocked(pw, "        ", dumpAll);
             }
+            pw.print("  Total procs: "); pw.print(numShownProcs);
+            pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
         }
 
         if (dumpAll) {
@@ -1598,8 +1646,7 @@
                 pw.println();
             }
             sepNeeded = true;
-            pw.print("  Total procs: "); pw.print(numShownProcs);
-                    pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
+
             if (mTrackingAssociations.size() > 0) {
                 pw.println();
                 pw.println("Tracking associations:");
@@ -1866,7 +1913,10 @@
         return outProcs;
     }
 
-    public void dumpCheckinLocked(PrintWriter pw, String reqPackage) {
+    /**
+     * Prints checkin style stats dump.
+     */
+    public void dumpCheckinLocked(PrintWriter pw, String reqPackage, int section) {
         final long now = SystemClock.uptimeMillis();
         final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                 mPackages.getMap();
@@ -1895,50 +1945,61 @@
         }
         pw.println();
         pw.print("config,"); pw.println(mRuntime);
-        for (int ip=0; ip<pkgMap.size(); ip++) {
-            final String pkgName = pkgMap.keyAt(ip);
-            if (reqPackage != null && !reqPackage.equals(pkgName)) {
-                continue;
-            }
-            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
-            for (int iu=0; iu<uids.size(); iu++) {
-                final int uid = uids.keyAt(iu);
-                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
-                for (int iv=0; iv<vpkgs.size(); iv++) {
-                    final long vers = vpkgs.keyAt(iv);
-                    final PackageState pkgState = vpkgs.valueAt(iv);
-                    final int NPROCS = pkgState.mProcesses.size();
-                    final int NSRVS = pkgState.mServices.size();
-                    final int NASCS = pkgState.mAssociations.size();
-                    for (int iproc=0; iproc<NPROCS; iproc++) {
-                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                        proc.dumpPackageProcCheckin(pw, pkgName, uid, vers,
-                                pkgState.mProcesses.keyAt(iproc), now);
-                    }
-                    for (int isvc=0; isvc<NSRVS; isvc++) {
-                        final String serviceName = DumpUtils.collapseString(pkgName,
-                                pkgState.mServices.keyAt(isvc));
-                        final ServiceState svc = pkgState.mServices.valueAt(isvc);
-                        svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now);
-                    }
-                    for (int iasc=0; iasc<NASCS; iasc++) {
-                        final String associationName = DumpUtils.collapseString(pkgName,
-                                pkgState.mAssociations.keyAt(iasc));
-                        final AssociationState asc = pkgState.mAssociations.valueAt(iasc);
-                        asc.dumpTimesCheckin(pw, pkgName, uid, vers, associationName, now);
+
+        if ((section & REPORT_PKG_STATS) != 0) {
+            for (int ip = 0; ip < pkgMap.size(); ip++) {
+                final String pkgName = pkgMap.keyAt(ip);
+                if (reqPackage != null && !reqPackage.equals(pkgName)) {
+                    continue;
+                }
+                final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+                for (int iu = 0; iu < uids.size(); iu++) {
+                    final int uid = uids.keyAt(iu);
+                    final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                    for (int iv = 0; iv < vpkgs.size(); iv++) {
+                        final long vers = vpkgs.keyAt(iv);
+                        final PackageState pkgState = vpkgs.valueAt(iv);
+                        final int NPROCS = pkgState.mProcesses.size();
+                        final int NSRVS = pkgState.mServices.size();
+                        final int NASCS = pkgState.mAssociations.size();
+                        if ((section & REPORT_PKG_PROC_STATS) != 0) {
+                            for (int iproc = 0; iproc < NPROCS; iproc++) {
+                                ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                                proc.dumpPackageProcCheckin(pw, pkgName, uid, vers,
+                                        pkgState.mProcesses.keyAt(iproc), now);
+                            }
+                        }
+                        if ((section & REPORT_PKG_SVC_STATS) != 0) {
+                            for (int isvc = 0; isvc < NSRVS; isvc++) {
+                                final String serviceName = DumpUtils.collapseString(pkgName,
+                                        pkgState.mServices.keyAt(isvc));
+                                final ServiceState svc = pkgState.mServices.valueAt(isvc);
+                                svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now);
+                            }
+                        }
+                        if ((section & REPORT_PKG_ASC_STATS) != 0) {
+                            for (int iasc = 0; iasc < NASCS; iasc++) {
+                                final String associationName = DumpUtils.collapseString(pkgName,
+                                        pkgState.mAssociations.keyAt(iasc));
+                                final AssociationState asc = pkgState.mAssociations.valueAt(iasc);
+                                asc.dumpTimesCheckin(pw, pkgName, uid, vers, associationName, now);
+                            }
+                        }
                     }
                 }
             }
         }
 
-        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
-        for (int ip=0; ip<procMap.size(); ip++) {
-            String procName = procMap.keyAt(ip);
-            SparseArray<ProcessState> uids = procMap.valueAt(ip);
-            for (int iu=0; iu<uids.size(); iu++) {
-                final int uid = uids.keyAt(iu);
-                final ProcessState procState = uids.valueAt(iu);
-                procState.dumpProcCheckin(pw, procName, uid, now);
+        if ((section & REPORT_PROC_STATS) != 0) {
+            ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+            for (int ip = 0; ip < procMap.size(); ip++) {
+                String procName = procMap.keyAt(ip);
+                SparseArray<ProcessState> uids = procMap.valueAt(ip);
+                for (int iu = 0; iu < uids.size(); iu++) {
+                    final int uid = uids.keyAt(iu);
+                    final ProcessState procState = uids.valueAt(iu);
+                    procState.dumpProcCheckin(pw, procName, uid, now);
+                }
             }
         }
         pw.print("total");
@@ -2013,9 +2074,10 @@
         }
     }
 
-    public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
-        final long token = proto.start(fieldId);
-
+    /**
+     * Writes to ProtoOutputStream.
+     */
+    public void writeToProto(ProtoOutputStream proto, long now, int section) {
         proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
         proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
                 mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
@@ -2024,15 +2086,15 @@
         proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime);
         proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss);
         boolean partial = true;
-        if ((mFlags&FLAG_SHUTDOWN) != 0) {
+        if ((mFlags & FLAG_SHUTDOWN) != 0) {
             proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN);
             partial = false;
         }
-        if ((mFlags&FLAG_SYSPROPS) != 0) {
+        if ((mFlags & FLAG_SYSPROPS) != 0) {
             proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS);
             partial = false;
         }
-        if ((mFlags&FLAG_COMPLETE) != 0) {
+        if ((mFlags & FLAG_COMPLETE) != 0) {
             proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE);
             partial = false;
         }
@@ -2041,31 +2103,34 @@
         }
 
         final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
-        for (int ip=0; ip<procMap.size(); ip++) {
-            final String procName = procMap.keyAt(ip);
-            final SparseArray<ProcessState> uids = procMap.valueAt(ip);
-            for (int iu=0; iu<uids.size(); iu++) {
-                final int uid = uids.keyAt(iu);
-                final ProcessState procState = uids.valueAt(iu);
-                procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName,
-                        uid, now);
-            }
-        }
-
-        final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
-                mPackages.getMap();
-        for (int ip = 0; ip < pkgMap.size(); ip++) {
-            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
-            for (int iu = 0; iu < uids.size(); iu++) {
-                final LongSparseArray<PackageState> vers = uids.valueAt(iu);
-                for (int iv = 0; iv < vers.size(); iv++) {
-                    final PackageState pkgState = vers.valueAt(iv);
-                    pkgState.writeToProto(proto, ProcessStatsSectionProto.PACKAGE_STATS, now);
+        if ((section & REPORT_PROC_STATS) != 0) {
+            for (int ip = 0; ip < procMap.size(); ip++) {
+                final String procName = procMap.keyAt(ip);
+                final SparseArray<ProcessState> uids = procMap.valueAt(ip);
+                for (int iu = 0; iu < uids.size(); iu++) {
+                    final int uid = uids.keyAt(iu);
+                    final ProcessState procState = uids.valueAt(iu);
+                    procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName,
+                            uid, now);
                 }
             }
         }
 
-        proto.end(token);
+        if ((section & REPORT_PKG_STATS) != 0) {
+            final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
+                    mPackages.getMap();
+            for (int ip = 0; ip < pkgMap.size(); ip++) {
+                final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+                for (int iu = 0; iu < uids.size(); iu++) {
+                    final LongSparseArray<PackageState> vers = uids.valueAt(iu);
+                    for (int iv = 0; iv < vers.size(); iv++) {
+                        final PackageState pkgState = vers.valueAt(iv);
+                        pkgState.writeToProto(proto, ProcessStatsSectionProto.PACKAGE_STATS, now,
+                                section);
+                    }
+                }
+            }
+        }
     }
 
     final public static class ProcessStateHolder {
@@ -2110,30 +2175,39 @@
             return as;
         }
 
-        public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+        /**
+         * Writes the containing stats into proto, with options to choose smaller sections.
+         */
+        public void writeToProto(ProtoOutputStream proto, long fieldId, long now, int section) {
             final long token = proto.start(fieldId);
 
             proto.write(ProcessStatsPackageProto.PACKAGE, mPackageName);
             proto.write(ProcessStatsPackageProto.UID, mUid);
             proto.write(ProcessStatsPackageProto.VERSION, mVersionCode);
 
-            for (int ip = 0; ip < mProcesses.size(); ip++) {
-                final String procName = mProcesses.keyAt(ip);
-                final ProcessState procState = mProcesses.valueAt(ip);
-                procState.writeToProto(proto, ProcessStatsPackageProto.PROCESS_STATS, procName,
-                        mUid, now);
+            if ((section & ProcessStats.REPORT_PKG_PROC_STATS) != 0) {
+                for (int ip = 0; ip < mProcesses.size(); ip++) {
+                    final String procName = mProcesses.keyAt(ip);
+                    final ProcessState procState = mProcesses.valueAt(ip);
+                    procState.writeToProto(proto, ProcessStatsPackageProto.PROCESS_STATS, procName,
+                            mUid, now);
+                }
             }
 
-            for (int is = 0; is < mServices.size(); is++) {
-                final ServiceState serviceState = mServices.valueAt(is);
-                serviceState.writeToProto(proto, ProcessStatsPackageProto.SERVICE_STATS,
-                        now);
+            if ((section & ProcessStats.REPORT_PKG_SVC_STATS) != 0) {
+                for (int is = 0; is < mServices.size(); is++) {
+                    final ServiceState serviceState = mServices.valueAt(is);
+                    serviceState.writeToProto(proto, ProcessStatsPackageProto.SERVICE_STATS,
+                            now);
+                }
             }
 
-            for (int ia=0; ia<mAssociations.size(); ia++) {
-                final AssociationState ascState = mAssociations.valueAt(ia);
-                ascState.writeToProto(proto, ProcessStatsPackageProto.ASSOCIATION_STATS,
-                        now);
+            if ((section & ProcessStats.REPORT_PKG_ASC_STATS) != 0) {
+                for (int ia = 0; ia < mAssociations.size(); ia++) {
+                    final AssociationState ascState = mAssociations.valueAt(ia);
+                    ascState.writeToProto(proto, ProcessStatsPackageProto.ASSOCIATION_STATS,
+                            now);
+                }
             }
 
             proto.end(token);
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
deleted file mode 100644
index d0f0272..0000000
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.backup;
-
-import android.app.backup.BackupAgent;
-import android.app.backup.BackupDataInput;
-import android.app.backup.BackupDataOutput;
-import android.app.backup.BackupTransport;
-import android.app.backup.RestoreDescription;
-import android.app.backup.RestoreSet;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructStat;
-import android.util.ArrayMap;
-import android.util.Base64;
-import android.util.Log;
-
-import libcore.io.IoUtils;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Backup transport for stashing stuff into a known location on disk, and
- * later restoring from there.  For testing only.
- */
-
-public class LocalTransport extends BackupTransport {
-    private static final String TAG = "LocalTransport";
-    private static final boolean DEBUG = false;
-
-    private static final String TRANSPORT_DIR_NAME
-            = "com.android.internal.backup.LocalTransport";
-
-    private static final String TRANSPORT_DESTINATION_STRING
-            = "Backing up to debug-only private cache";
-
-    private static final String TRANSPORT_DATA_MANAGEMENT_LABEL
-            = "";
-
-    private static final String INCREMENTAL_DIR = "_delta";
-    private static final String FULL_DATA_DIR = "_full";
-
-    // The currently-active restore set always has the same (nonzero!) token
-    private static final long CURRENT_SET_TOKEN = 1;
-
-    // Size quotas at reasonable values, similar to the current cloud-storage limits
-    private static final long FULL_BACKUP_SIZE_QUOTA = 25 * 1024 * 1024;
-    private static final long KEY_VALUE_BACKUP_SIZE_QUOTA = 5 * 1024 * 1024;
-
-    private Context mContext;
-    private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
-    private File mCurrentSetDir = new File(mDataDir, Long.toString(CURRENT_SET_TOKEN));
-    private File mCurrentSetIncrementalDir = new File(mCurrentSetDir, INCREMENTAL_DIR);
-    private File mCurrentSetFullDir = new File(mCurrentSetDir, FULL_DATA_DIR);
-
-    private PackageInfo[] mRestorePackages = null;
-    private int mRestorePackage = -1;  // Index into mRestorePackages
-    private int mRestoreType;
-    private File mRestoreSetDir;
-    private File mRestoreSetIncrementalDir;
-    private File mRestoreSetFullDir;
-
-    // Additional bookkeeping for full backup
-    private String mFullTargetPackage;
-    private ParcelFileDescriptor mSocket;
-    private FileInputStream mSocketInputStream;
-    private BufferedOutputStream mFullBackupOutputStream;
-    private byte[] mFullBackupBuffer;
-    private long mFullBackupSize;
-
-    private FileInputStream mCurFullRestoreStream;
-    private FileOutputStream mFullRestoreSocketStream;
-    private byte[] mFullRestoreBuffer;
-    private final LocalTransportParameters mParameters;
-
-    private void makeDataDirs() {
-        mCurrentSetDir.mkdirs();
-        mCurrentSetFullDir.mkdir();
-        mCurrentSetIncrementalDir.mkdir();
-    }
-
-    public LocalTransport(Context context, LocalTransportParameters parameters) {
-        mContext = context;
-        mParameters = parameters;
-        makeDataDirs();
-    }
-
-    LocalTransportParameters getParameters() {
-        return mParameters;
-    }
-
-    @Override
-    public String name() {
-        return new ComponentName(mContext, this.getClass()).flattenToShortString();
-    }
-
-    @Override
-    public Intent configurationIntent() {
-        // The local transport is not user-configurable
-        return null;
-    }
-
-    @Override
-    public String currentDestinationString() {
-        return TRANSPORT_DESTINATION_STRING;
-    }
-
-    public Intent dataManagementIntent() {
-        // The local transport does not present a data-management UI
-        // TODO: consider adding simple UI to wipe the archives entirely,
-        // for cleaning up the cache partition.
-        return null;
-    }
-
-    public String dataManagementLabel() {
-        return TRANSPORT_DATA_MANAGEMENT_LABEL;
-    }
-
-    @Override
-    public String transportDirName() {
-        return TRANSPORT_DIR_NAME;
-    }
-
-    @Override
-    public int getTransportFlags() {
-        int flags = super.getTransportFlags();
-        // Testing for a fake flag and having it set as a boolean in settings prevents anyone from
-        // using this it to pull data from the agent
-        if (mParameters.isFakeEncryptionFlag()) {
-            flags |= BackupAgent.FLAG_FAKE_CLIENT_SIDE_ENCRYPTION_ENABLED;
-        }
-        return flags;
-    }
-
-    @Override
-    public long requestBackupTime() {
-        // any time is a good time for local backup
-        return 0;
-    }
-
-    @Override
-    public int initializeDevice() {
-        if (DEBUG) Log.v(TAG, "wiping all data");
-        deleteContents(mCurrentSetDir);
-        makeDataDirs();
-        return TRANSPORT_OK;
-    }
-
-    // Encapsulation of a single k/v element change
-    private class KVOperation {
-        final String key;     // Element filename, not the raw key, for efficiency
-        final byte[] value;   // null when this is a deletion operation
-
-        KVOperation(String k, byte[] v) {
-            key = k;
-            value = v;
-        }
-    }
-
-    @Override
-    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
-        return performBackup(packageInfo, data, /*flags=*/ 0);
-    }
-
-    @Override
-    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data, int flags) {
-        boolean isIncremental = (flags & FLAG_INCREMENTAL) != 0;
-        boolean isNonIncremental = (flags & FLAG_NON_INCREMENTAL) != 0;
-
-        if (isIncremental) {
-            Log.i(TAG, "Performing incremental backup for " + packageInfo.packageName);
-        } else if (isNonIncremental) {
-            Log.i(TAG, "Performing non-incremental backup for " + packageInfo.packageName);
-        } else {
-            Log.i(TAG, "Performing backup for " + packageInfo.packageName);
-        }
-
-        if (DEBUG) {
-            try {
-                StructStat ss = Os.fstat(data.getFileDescriptor());
-                Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName
-                        + " size=" + ss.st_size + " flags=" + flags);
-            } catch (ErrnoException e) {
-                Log.w(TAG, "Unable to stat input file in performBackup() on "
-                        + packageInfo.packageName);
-            }
-        }
-
-        File packageDir = new File(mCurrentSetIncrementalDir, packageInfo.packageName);
-        boolean hasDataForPackage = !packageDir.mkdirs();
-
-        if (isIncremental) {
-            if (mParameters.isNonIncrementalOnly() || !hasDataForPackage) {
-                if (mParameters.isNonIncrementalOnly()) {
-                    Log.w(TAG, "Transport is in non-incremental only mode.");
-
-                } else {
-                    Log.w(TAG,
-                            "Requested incremental, but transport currently stores no data for the "
-                                    + "package, requesting non-incremental retry.");
-                }
-                return TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED;
-            }
-        }
-        if (isNonIncremental && hasDataForPackage) {
-            Log.w(TAG, "Requested non-incremental, deleting existing data.");
-            clearBackupData(packageInfo);
-            packageDir.mkdirs();
-        }
-
-        // Each 'record' in the restore set is kept in its own file, named by
-        // the record key.  Wind through the data file, extracting individual
-        // record operations and building a list of all the updates to apply
-        // in this update.
-        final ArrayList<KVOperation> changeOps;
-        try {
-            changeOps = parseBackupStream(data);
-        } catch (IOException e) {
-            // oops, something went wrong.  abort the operation and return error.
-            Log.v(TAG, "Exception reading backup input", e);
-            return TRANSPORT_ERROR;
-        }
-
-        // Okay, now we've parsed out the delta's individual operations.  We need to measure
-        // the effect against what we already have in the datastore to detect quota overrun.
-        // So, we first need to tally up the current in-datastore size per key.
-        final ArrayMap<String, Integer> datastore = new ArrayMap<>();
-        int totalSize = parseKeySizes(packageDir, datastore);
-
-        // ... and now figure out the datastore size that will result from applying the
-        // sequence of delta operations
-        if (DEBUG) {
-            if (changeOps.size() > 0) {
-                Log.v(TAG, "Calculating delta size impact");
-            } else {
-                Log.v(TAG, "No operations in backup stream, so no size change");
-            }
-        }
-        int updatedSize = totalSize;
-        for (KVOperation op : changeOps) {
-            // Deduct the size of the key we're about to replace, if any
-            final Integer curSize = datastore.get(op.key);
-            if (curSize != null) {
-                updatedSize -= curSize.intValue();
-                if (DEBUG && op.value == null) {
-                    Log.v(TAG, "  delete " + op.key + ", updated total " + updatedSize);
-                }
-            }
-
-            // And add back the size of the value we're about to store, if any
-            if (op.value != null) {
-                updatedSize += op.value.length;
-                if (DEBUG) {
-                    Log.v(TAG, ((curSize == null) ? "  new " : "  replace ")
-                            +  op.key + ", updated total " + updatedSize);
-                }
-            }
-        }
-
-        // If our final size is over quota, report the failure
-        if (updatedSize > KEY_VALUE_BACKUP_SIZE_QUOTA) {
-            if (DEBUG) {
-                Log.i(TAG, "New datastore size " + updatedSize
-                        + " exceeds quota " + KEY_VALUE_BACKUP_SIZE_QUOTA);
-            }
-            return TRANSPORT_QUOTA_EXCEEDED;
-        }
-
-        // No problem with storage size, so go ahead and apply the delta operations
-        // (in the order that the app provided them)
-        for (KVOperation op : changeOps) {
-            File element = new File(packageDir, op.key);
-
-            // this is either a deletion or a rewrite-from-zero, so we can just remove
-            // the existing file and proceed in either case.
-            element.delete();
-
-            // if this wasn't a deletion, put the new data in place
-            if (op.value != null) {
-                try (FileOutputStream out = new FileOutputStream(element)) {
-                    out.write(op.value, 0, op.value.length);
-                } catch (IOException e) {
-                    Log.e(TAG, "Unable to update key file " + element);
-                    return TRANSPORT_ERROR;
-                }
-            }
-        }
-        return TRANSPORT_OK;
-    }
-
-    // Parses a backup stream into individual key/value operations
-    private ArrayList<KVOperation> parseBackupStream(ParcelFileDescriptor data)
-            throws IOException {
-        ArrayList<KVOperation> changeOps = new ArrayList<>();
-        BackupDataInput changeSet = new BackupDataInput(data.getFileDescriptor());
-        while (changeSet.readNextHeader()) {
-            String key = changeSet.getKey();
-            String base64Key = new String(Base64.encode(key.getBytes(), Base64.NO_WRAP));
-            int dataSize = changeSet.getDataSize();
-            if (DEBUG) {
-                Log.v(TAG, "  Delta operation key " + key + "   size " + dataSize
-                        + "   key64 " + base64Key);
-            }
-
-            byte[] buf = (dataSize >= 0) ? new byte[dataSize] : null;
-            if (dataSize >= 0) {
-                changeSet.readEntityData(buf, 0, dataSize);
-            }
-            changeOps.add(new KVOperation(base64Key, buf));
-        }
-        return changeOps;
-    }
-
-    // Reads the given datastore directory, building a table of the value size of each
-    // keyed element, and returning the summed total.
-    private int parseKeySizes(File packageDir, ArrayMap<String, Integer> datastore) {
-        int totalSize = 0;
-        final String[] elements = packageDir.list();
-        if (elements != null) {
-            if (DEBUG) {
-                Log.v(TAG, "Existing datastore contents:");
-            }
-            for (String file : elements) {
-                File element = new File(packageDir, file);
-                String key = file;  // filename
-                int size = (int) element.length();
-                totalSize += size;
-                if (DEBUG) {
-                    Log.v(TAG, "  key " + key + "   size " + size);
-                }
-                datastore.put(key, size);
-            }
-            if (DEBUG) {
-                Log.v(TAG, "  TOTAL: " + totalSize);
-            }
-        } else {
-            if (DEBUG) {
-                Log.v(TAG, "No existing data for this package");
-            }
-        }
-        return totalSize;
-    }
-
-    // Deletes the contents but not the given directory
-    private void deleteContents(File dirname) {
-        File[] contents = dirname.listFiles();
-        if (contents != null) {
-            for (File f : contents) {
-                if (f.isDirectory()) {
-                    // delete the directory's contents then fall through
-                    // and delete the directory itself.
-                    deleteContents(f);
-                }
-                f.delete();
-            }
-        }
-    }
-
-    @Override
-    public int clearBackupData(PackageInfo packageInfo) {
-        if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
-
-        File packageDir = new File(mCurrentSetIncrementalDir, packageInfo.packageName);
-        final File[] fileset = packageDir.listFiles();
-        if (fileset != null) {
-            for (File f : fileset) {
-                f.delete();
-            }
-            packageDir.delete();
-        }
-
-        packageDir = new File(mCurrentSetFullDir, packageInfo.packageName);
-        final File[] tarballs = packageDir.listFiles();
-        if (tarballs != null) {
-            for (File f : tarballs) {
-                f.delete();
-            }
-            packageDir.delete();
-        }
-
-        return TRANSPORT_OK;
-    }
-
-    @Override
-    public int finishBackup() {
-        if (DEBUG) Log.v(TAG, "finishBackup() of " + mFullTargetPackage);
-        return tearDownFullBackup();
-    }
-
-    // ------------------------------------------------------------------------------------
-    // Full backup handling
-
-    private int tearDownFullBackup() {
-        if (mSocket != null) {
-            try {
-                if (mFullBackupOutputStream != null) {
-                    mFullBackupOutputStream.flush();
-                    mFullBackupOutputStream.close();
-                }
-                mSocketInputStream = null;
-                mFullTargetPackage = null;
-                mSocket.close();
-            } catch (IOException e) {
-                if (DEBUG) {
-                    Log.w(TAG, "Exception caught in tearDownFullBackup()", e);
-                }
-                return TRANSPORT_ERROR;
-            } finally {
-                mSocket = null;
-                mFullBackupOutputStream = null;
-            }
-        }
-        return TRANSPORT_OK;
-    }
-
-    private File tarballFile(String pkgName) {
-        return new File(mCurrentSetFullDir, pkgName);
-    }
-
-    @Override
-    public long requestFullBackupTime() {
-        return 0;
-    }
-
-    @Override
-    public int checkFullBackupSize(long size) {
-        int result = TRANSPORT_OK;
-        // Decline zero-size "backups"
-        if (size <= 0) {
-            result = TRANSPORT_PACKAGE_REJECTED;
-        } else if (size > FULL_BACKUP_SIZE_QUOTA) {
-            result = TRANSPORT_QUOTA_EXCEEDED;
-        }
-        if (result != TRANSPORT_OK) {
-            if (DEBUG) {
-                Log.v(TAG, "Declining backup of size " + size);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) {
-        if (mSocket != null) {
-            Log.e(TAG, "Attempt to initiate full backup while one is in progress");
-            return TRANSPORT_ERROR;
-        }
-
-        if (DEBUG) {
-            Log.i(TAG, "performFullBackup : " + targetPackage);
-        }
-
-        // We know a priori that we run in the system process, so we need to make
-        // sure to dup() our own copy of the socket fd.  Transports which run in
-        // their own processes must not do this.
-        try {
-            mFullBackupSize = 0;
-            mSocket = ParcelFileDescriptor.dup(socket.getFileDescriptor());
-            mSocketInputStream = new FileInputStream(mSocket.getFileDescriptor());
-        } catch (IOException e) {
-            Log.e(TAG, "Unable to process socket for full backup");
-            return TRANSPORT_ERROR;
-        }
-
-        mFullTargetPackage = targetPackage.packageName;
-        mFullBackupBuffer = new byte[4096];
-
-        return TRANSPORT_OK;
-    }
-
-    @Override
-    public int sendBackupData(final int numBytes) {
-        if (mSocket == null) {
-            Log.w(TAG, "Attempted sendBackupData before performFullBackup");
-            return TRANSPORT_ERROR;
-        }
-
-        mFullBackupSize += numBytes;
-        if (mFullBackupSize > FULL_BACKUP_SIZE_QUOTA) {
-            return TRANSPORT_QUOTA_EXCEEDED;
-        }
-
-        if (numBytes > mFullBackupBuffer.length) {
-            mFullBackupBuffer = new byte[numBytes];
-        }
-
-        if (mFullBackupOutputStream == null) {
-            FileOutputStream tarstream;
-            try {
-                File tarball = tarballFile(mFullTargetPackage);
-                tarstream = new FileOutputStream(tarball);
-            } catch (FileNotFoundException e) {
-                return TRANSPORT_ERROR;
-            }
-            mFullBackupOutputStream = new BufferedOutputStream(tarstream);
-        }
-
-        int bytesLeft = numBytes;
-        while (bytesLeft > 0) {
-            try {
-            int nRead = mSocketInputStream.read(mFullBackupBuffer, 0, bytesLeft);
-            if (nRead < 0) {
-                // Something went wrong if we expect data but saw EOD
-                Log.w(TAG, "Unexpected EOD; failing backup");
-                return TRANSPORT_ERROR;
-            }
-            mFullBackupOutputStream.write(mFullBackupBuffer, 0, nRead);
-            bytesLeft -= nRead;
-            } catch (IOException e) {
-                Log.e(TAG, "Error handling backup data for " + mFullTargetPackage);
-                return TRANSPORT_ERROR;
-            }
-        }
-        if (DEBUG) {
-            Log.v(TAG, "   stored " + numBytes + " of data");
-        }
-        return TRANSPORT_OK;
-    }
-
-    // For now we can't roll back, so just tear everything down.
-    @Override
-    public void cancelFullBackup() {
-        if (DEBUG) {
-            Log.i(TAG, "Canceling full backup of " + mFullTargetPackage);
-        }
-        File archive = tarballFile(mFullTargetPackage);
-        tearDownFullBackup();
-        if (archive.exists()) {
-            archive.delete();
-        }
-    }
-
-    // ------------------------------------------------------------------------------------
-    // Restore handling
-    static final long[] POSSIBLE_SETS = { 2, 3, 4, 5, 6, 7, 8, 9 };
-
-    @Override
-    public RestoreSet[] getAvailableRestoreSets() {
-        long[] existing = new long[POSSIBLE_SETS.length + 1];
-        int num = 0;
-
-        // see which possible non-current sets exist...
-        for (long token : POSSIBLE_SETS) {
-            if ((new File(mDataDir, Long.toString(token))).exists()) {
-                existing[num++] = token;
-            }
-        }
-        // ...and always the currently-active set last
-        existing[num++] = CURRENT_SET_TOKEN;
-
-        RestoreSet[] available = new RestoreSet[num];
-        for (int i = 0; i < available.length; i++) {
-            available[i] = new RestoreSet("Local disk image", "flash", existing[i]);
-        }
-        return available;
-    }
-
-    @Override
-    public long getCurrentRestoreSet() {
-        // The current restore set always has the same token
-        return CURRENT_SET_TOKEN;
-    }
-
-    @Override
-    public int startRestore(long token, PackageInfo[] packages) {
-        if (DEBUG) Log.v(TAG, "start restore " + token + " : " + packages.length
-                + " matching packages");
-        mRestorePackages = packages;
-        mRestorePackage = -1;
-        mRestoreSetDir = new File(mDataDir, Long.toString(token));
-        mRestoreSetIncrementalDir = new File(mRestoreSetDir, INCREMENTAL_DIR);
-        mRestoreSetFullDir = new File(mRestoreSetDir, FULL_DATA_DIR);
-        return TRANSPORT_OK;
-    }
-
-    @Override
-    public RestoreDescription nextRestorePackage() {
-        if (DEBUG) {
-            Log.v(TAG, "nextRestorePackage() : mRestorePackage=" + mRestorePackage
-                    + " length=" + mRestorePackages.length);
-        }
-        if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
-
-        boolean found = false;
-        while (++mRestorePackage < mRestorePackages.length) {
-            String name = mRestorePackages[mRestorePackage].packageName;
-
-            // If we have key/value data for this package, deliver that
-            // skip packages where we have a data dir but no actual contents
-            String[] contents = (new File(mRestoreSetIncrementalDir, name)).list();
-            if (contents != null && contents.length > 0) {
-                if (DEBUG) {
-                    Log.v(TAG, "  nextRestorePackage(TYPE_KEY_VALUE) @ "
-                        + mRestorePackage + " = " + name);
-                }
-                mRestoreType = RestoreDescription.TYPE_KEY_VALUE;
-                found = true;
-            }
-
-            if (!found) {
-                // No key/value data; check for [non-empty] full data
-                File maybeFullData = new File(mRestoreSetFullDir, name);
-                if (maybeFullData.length() > 0) {
-                    if (DEBUG) {
-                        Log.v(TAG, "  nextRestorePackage(TYPE_FULL_STREAM) @ "
-                                + mRestorePackage + " = " + name);
-                    }
-                    mRestoreType = RestoreDescription.TYPE_FULL_STREAM;
-                    mCurFullRestoreStream = null;   // ensure starting from the ground state
-                    found = true;
-                }
-            }
-
-            if (found) {
-                return new RestoreDescription(name, mRestoreType);
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, "  ... package @ " + mRestorePackage + " = " + name
-                        + " has no data; skipping");
-            }
-        }
-
-        if (DEBUG) Log.v(TAG, "  no more packages to restore");
-        return RestoreDescription.NO_MORE_PACKAGES;
-    }
-
-    @Override
-    public int getRestoreData(ParcelFileDescriptor outFd) {
-        if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
-        if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called");
-        if (mRestoreType != RestoreDescription.TYPE_KEY_VALUE) {
-            throw new IllegalStateException("getRestoreData(fd) for non-key/value dataset");
-        }
-        File packageDir = new File(mRestoreSetIncrementalDir,
-                mRestorePackages[mRestorePackage].packageName);
-
-        // The restore set is the concatenation of the individual record blobs,
-        // each of which is a file in the package's directory.  We return the
-        // data in lexical order sorted by key, so that apps which use synthetic
-        // keys like BLOB_1, BLOB_2, etc will see the date in the most obvious
-        // order.
-        ArrayList<DecodedFilename> blobs = contentsByKey(packageDir);
-        if (blobs == null) {  // nextRestorePackage() ensures the dir exists, so this is an error
-            Log.e(TAG, "No keys for package: " + packageDir);
-            return TRANSPORT_ERROR;
-        }
-
-        // We expect at least some data if the directory exists in the first place
-        if (DEBUG) Log.v(TAG, "  getRestoreData() found " + blobs.size() + " key files");
-        BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor());
-        try {
-            for (DecodedFilename keyEntry : blobs) {
-                File f = keyEntry.file;
-                FileInputStream in = new FileInputStream(f);
-                try {
-                    int size = (int) f.length();
-                    byte[] buf = new byte[size];
-                    in.read(buf);
-                    if (DEBUG) Log.v(TAG, "    ... key=" + keyEntry.key + " size=" + size);
-                    out.writeEntityHeader(keyEntry.key, size);
-                    out.writeEntityData(buf, size);
-                } finally {
-                    in.close();
-                }
-            }
-            return TRANSPORT_OK;
-        } catch (IOException e) {
-            Log.e(TAG, "Unable to read backup records", e);
-            return TRANSPORT_ERROR;
-        }
-    }
-
-    static class DecodedFilename implements Comparable<DecodedFilename> {
-        public File file;
-        public String key;
-
-        public DecodedFilename(File f) {
-            file = f;
-            key = new String(Base64.decode(f.getName(), Base64.DEFAULT));
-        }
-
-        @Override
-        public int compareTo(DecodedFilename other) {
-            // sorts into ascending lexical order by decoded key
-            return key.compareTo(other.key);
-        }
-    }
-
-    // Return a list of the files in the given directory, sorted lexically by
-    // the Base64-decoded file name, not by the on-disk filename
-    private ArrayList<DecodedFilename> contentsByKey(File dir) {
-        File[] allFiles = dir.listFiles();
-        if (allFiles == null || allFiles.length == 0) {
-            return null;
-        }
-
-        // Decode the filenames into keys then sort lexically by key
-        ArrayList<DecodedFilename> contents = new ArrayList<DecodedFilename>();
-        for (File f : allFiles) {
-            contents.add(new DecodedFilename(f));
-        }
-        Collections.sort(contents);
-        return contents;
-    }
-
-    @Override
-    public void finishRestore() {
-        if (DEBUG) Log.v(TAG, "finishRestore()");
-        if (mRestoreType == RestoreDescription.TYPE_FULL_STREAM) {
-            resetFullRestoreState();
-        }
-        mRestoreType = 0;
-    }
-
-    // ------------------------------------------------------------------------------------
-    // Full restore handling
-
-    private void resetFullRestoreState() {
-        IoUtils.closeQuietly(mCurFullRestoreStream);
-        mCurFullRestoreStream = null;
-        mFullRestoreSocketStream = null;
-        mFullRestoreBuffer = null;
-    }
-
-    /**
-     * Ask the transport to provide data for the "current" package being restored.  The
-     * transport then writes some data to the socket supplied to this call, and returns
-     * the number of bytes written.  The system will then read that many bytes and
-     * stream them to the application's agent for restore, then will call this method again
-     * to receive the next chunk of the archive.  This sequence will be repeated until the
-     * transport returns zero indicating that all of the package's data has been delivered
-     * (or returns a negative value indicating some sort of hard error condition at the
-     * transport level).
-     *
-     * <p>After this method returns zero, the system will then call
-     * {@link #getNextFullRestorePackage()} to begin the restore process for the next
-     * application, and the sequence begins again.
-     *
-     * @param socket The file descriptor that the transport will use for delivering the
-     *    streamed archive.
-     * @return 0 when no more data for the current package is available.  A positive value
-     *    indicates the presence of that much data to be delivered to the app.  A negative
-     *    return value is treated as equivalent to {@link BackupTransport#TRANSPORT_ERROR},
-     *    indicating a fatal error condition that precludes further restore operations
-     *    on the current dataset.
-     */
-    @Override
-    public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
-        if (mRestoreType != RestoreDescription.TYPE_FULL_STREAM) {
-            throw new IllegalStateException("Asked for full restore data for non-stream package");
-        }
-
-        // first chunk?
-        if (mCurFullRestoreStream == null) {
-            final String name = mRestorePackages[mRestorePackage].packageName;
-            if (DEBUG) Log.i(TAG, "Starting full restore of " + name);
-            File dataset = new File(mRestoreSetFullDir, name);
-            try {
-                mCurFullRestoreStream = new FileInputStream(dataset);
-            } catch (IOException e) {
-                // If we can't open the target package's tarball, we return the single-package
-                // error code and let the caller go on to the next package.
-                Log.e(TAG, "Unable to read archive for " + name);
-                return TRANSPORT_PACKAGE_REJECTED;
-            }
-            mFullRestoreSocketStream = new FileOutputStream(socket.getFileDescriptor());
-            mFullRestoreBuffer = new byte[2*1024];
-        }
-
-        int nRead;
-        try {
-            nRead = mCurFullRestoreStream.read(mFullRestoreBuffer);
-            if (nRead < 0) {
-                // EOF: tell the caller we're done
-                nRead = NO_MORE_DATA;
-            } else if (nRead == 0) {
-                // This shouldn't happen when reading a FileInputStream; we should always
-                // get either a positive nonzero byte count or -1.  Log the situation and
-                // treat it as EOF.
-                Log.w(TAG, "read() of archive file returned 0; treating as EOF");
-                nRead = NO_MORE_DATA;
-            } else {
-                if (DEBUG) {
-                    Log.i(TAG, "   delivering restore chunk: " + nRead);
-                }
-                mFullRestoreSocketStream.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.
-        }
-
-        return nRead;
-    }
-
-    /**
-     * If the OS encounters an error while processing {@link RestoreDescription#TYPE_FULL_STREAM}
-     * data for restore, it will invoke this method to tell the transport that it should
-     * abandon the data download for the current package.  The OS will then either call
-     * {@link #nextRestorePackage()} again to move on to restoring the next package in the
-     * set being iterated over, or will call {@link #finishRestore()} to shut down the restore
-     * operation.
-     *
-     * @return {@link #TRANSPORT_OK} if the transport was successful in shutting down the
-     *    current stream cleanly, or {@link #TRANSPORT_ERROR} to indicate a serious
-     *    transport-level failure.  If the transport reports an error here, the entire restore
-     *    operation will immediately be finished with no further attempts to restore app data.
-     */
-    @Override
-    public int abortFullRestore() {
-        if (mRestoreType != RestoreDescription.TYPE_FULL_STREAM) {
-            throw new IllegalStateException("abortFullRestore() but not currently restoring");
-        }
-        resetFullRestoreState();
-        mRestoreType = 0;
-        return TRANSPORT_OK;
-    }
-
-    @Override
-    public long getBackupQuota(String packageName, boolean isFullBackup) {
-        return isFullBackup ? FULL_BACKUP_SIZE_QUOTA : KEY_VALUE_BACKUP_SIZE_QUOTA;
-    }
-}
diff --git a/core/java/com/android/internal/backup/LocalTransportParameters.java b/core/java/com/android/internal/backup/LocalTransportParameters.java
deleted file mode 100644
index 2427d39..0000000
--- a/core/java/com/android/internal/backup/LocalTransportParameters.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.internal.backup;
-
-import android.util.KeyValueSettingObserver;
-import android.content.ContentResolver;
-import android.os.Handler;
-import android.provider.Settings;
-import android.util.KeyValueListParser;
-
-class LocalTransportParameters extends KeyValueSettingObserver {
-    private static final String TAG = "LocalTransportParams";
-    private static final String SETTING = Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS;
-    private static final String KEY_FAKE_ENCRYPTION_FLAG = "fake_encryption_flag";
-    private static final String KEY_NON_INCREMENTAL_ONLY = "non_incremental_only";
-
-    private boolean mFakeEncryptionFlag;
-    private boolean mIsNonIncrementalOnly;
-
-    LocalTransportParameters(Handler handler, ContentResolver resolver) {
-        super(handler, resolver, Settings.Secure.getUriFor(SETTING));
-    }
-
-    boolean isFakeEncryptionFlag() {
-        return mFakeEncryptionFlag;
-    }
-
-    boolean isNonIncrementalOnly() {
-        return mIsNonIncrementalOnly;
-    }
-
-    public String getSettingValue(ContentResolver resolver) {
-        return Settings.Secure.getString(resolver, SETTING);
-    }
-
-    public void update(KeyValueListParser parser) {
-        mFakeEncryptionFlag = parser.getBoolean(KEY_FAKE_ENCRYPTION_FLAG, false);
-        mIsNonIncrementalOnly = parser.getBoolean(KEY_NON_INCREMENTAL_ONLY, false);
-    }
-}
diff --git a/core/java/com/android/internal/backup/LocalTransportService.java b/core/java/com/android/internal/backup/LocalTransportService.java
deleted file mode 100644
index 69c48e2..0000000
--- a/core/java/com/android/internal/backup/LocalTransportService.java
+++ /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.
- */
-
-package com.android.internal.backup;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class LocalTransportService extends Service {
-    private static LocalTransport sTransport = null;
-
-    @Override
-    public void onCreate() {
-        if (sTransport == null) {
-            LocalTransportParameters parameters =
-                    new LocalTransportParameters(getMainThreadHandler(), getContentResolver());
-            sTransport = new LocalTransport(this, parameters);
-        }
-        sTransport.getParameters().start();
-    }
-
-    @Override
-    public void onDestroy() {
-        sTransport.getParameters().stop();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return sTransport.getBinder();
-    }
-}
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index b33a5c4..81dab2f 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -232,6 +232,7 @@
         displayName = FileUtils.buildValidFatFilename(displayName);
 
         final File before = getFileForDocId(docId);
+        final File beforeVisibleFile = getFileForDocId(docId, true);
         final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName);
         if (!before.renameTo(after)) {
             throw new IllegalStateException("Failed to rename to " + after);
@@ -241,7 +242,6 @@
         onDocIdChanged(docId);
         onDocIdChanged(afterDocId);
 
-        final File beforeVisibleFile = getFileForDocId(docId, true);
         final File afterVisibleFile = getFileForDocId(afterDocId, true);
         moveInMediaStore(beforeVisibleFile, afterVisibleFile);
 
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 cb282b6..0080ace 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -66,13 +66,13 @@
         return !TextUtils.isEmpty(doubleTapSensorType());
     }
 
-    public boolean reachGestureEnabled(int user) {
-        return boolSettingDefaultOn(Settings.Secure.DOZE_REACH_GESTURE, user)
-                && reachGestureAvailable();
+    public boolean wakeLockScreenGestureEnabled(int user) {
+        return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, user)
+                && wakeLockScreenGestureAvailable();
     }
 
-    public boolean reachGestureAvailable() {
-        return !TextUtils.isEmpty(reachSensorType());
+    public boolean wakeLockScreenGestureAvailable() {
+        return !TextUtils.isEmpty(wakeLockScreenSensorType());
     }
 
     public boolean wakeScreenGestureEnabled(int user) {
@@ -92,8 +92,8 @@
         return mContext.getResources().getString(R.string.config_dozeLongPressSensorType);
     }
 
-    public String reachSensorType() {
-        return mContext.getResources().getString(R.string.config_dozeReachSensorType);
+    public String wakeLockScreenSensorType() {
+        return mContext.getResources().getString(R.string.config_dozeWakeLockScreenSensorType);
     }
 
     public String wakeScreenSensorType() {
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index c32894d..2671781 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -28,7 +28,6 @@
 interface IInputMethodPrivilegedOperations {
     void setImeWindowStatus(int vis, int backDisposition);
     void reportStartInput(in IBinder startInputToken);
-    void clearLastInputMethodWindowForTransition();
     IInputContentUriToken createInputContentUriToken(in Uri contentUri, in String packageName);
     void reportFullscreenMode(boolean fullscreen);
     void setInputMethod(String id);
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index f0e8dc5..cdb986a 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -135,22 +135,6 @@
     }
 
     /**
-     * Calls {@link IInputMethodPrivilegedOperations#clearLastInputMethodWindowForTransition()}.
-     */
-    @AnyThread
-    public void clearLastInputMethodWindowForTransition() {
-        final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
-        if (ops == null) {
-            return;
-        }
-        try {
-            ops.clearLastInputMethodWindowForTransition();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String)}.
      *
      * @param contentUri Content URI to which a temporary read permission should be granted
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperationsRegistry.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperationsRegistry.java
index 3255153..1436aed 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperationsRegistry.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperationsRegistry.java
@@ -29,12 +29,19 @@
 /**
  * A weak-reference-based mapper from IME token to {@link InputMethodPrivilegedOperations} that is
  * used only to support deprecated IME APIs in {@link android.view.inputmethod.InputMethodManager}.
+ *
+ * <p>This class is designed to be used as a per-process global registry.</p>
  */
 public final class InputMethodPrivilegedOperationsRegistry {
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private final WeakHashMap<IBinder, WeakReference<InputMethodPrivilegedOperations>>
-            mRegistry = new WeakHashMap<>();
+    private InputMethodPrivilegedOperationsRegistry() {
+        // Not intended to be instantiated.
+    }
+
+    private static final Object sLock = new Object();
+
+    @Nullable
+    @GuardedBy("sLock")
+    private static WeakHashMap<IBinder, WeakReference<InputMethodPrivilegedOperations>> sRegistry;
 
     @Nullable
     private static InputMethodPrivilegedOperations sNop;
@@ -62,10 +69,13 @@
      * @param ops {@link InputMethodPrivilegedOperations} to be associated with the given IME token
      */
     @AnyThread
-    public void put(IBinder token, InputMethodPrivilegedOperations ops) {
-        synchronized (mLock) {
+    public static void put(IBinder token, InputMethodPrivilegedOperations ops) {
+        synchronized (sLock) {
+            if (sRegistry == null) {
+                sRegistry = new WeakHashMap<>();
+            }
             final WeakReference<InputMethodPrivilegedOperations> previousOps =
-                    mRegistry.put(token, new WeakReference<>(ops));
+                    sRegistry.put(token, new WeakReference<>(ops));
             if (previousOps != null) {
                 throw new IllegalStateException(previousOps.get() + " is already registered for "
                         + " this token=" + token + " newOps=" + ops);
@@ -84,9 +94,12 @@
      */
     @NonNull
     @AnyThread
-    public InputMethodPrivilegedOperations get(IBinder token) {
-        synchronized (mLock) {
-            final WeakReference<InputMethodPrivilegedOperations> wrapperRef = mRegistry.get(token);
+    public static InputMethodPrivilegedOperations get(IBinder token) {
+        synchronized (sLock) {
+            if (sRegistry == null) {
+                return getNopOps();
+            }
+            final WeakReference<InputMethodPrivilegedOperations> wrapperRef = sRegistry.get(token);
             if (wrapperRef == null) {
                 return getNopOps();
             }
@@ -108,9 +121,15 @@
      * @param token IME token to be removed.
      */
     @AnyThread
-    public void remove(IBinder token) {
-        synchronized (mLock) {
-            mRegistry.remove(token);
+    public static void remove(IBinder token) {
+        synchronized (sLock) {
+            if (sRegistry == null) {
+                return;
+            }
+            sRegistry.remove(token);
+            if (sRegistry.isEmpty()) {
+                sRegistry = null;
+            }
         }
     }
 }
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 31f13c3..33b9ff7 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -337,6 +337,9 @@
 
     private final PlatformIdleStateCallback mPlatformIdleStateCallback;
 
+    /**
+     * This handler is running on {@link BackgroundThread}.
+     */
     final class MyHandler extends Handler {
         public MyHandler(Looper looper) {
             super(looper, null, true);
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index c0c358d..856712f 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -436,6 +436,12 @@
     }
 
     public void setSamplingInterval(int samplingInterval) {
+        if (samplingInterval <= 0) {
+            Slog.w(TAG, "Ignored invalid sampling interval (value must be positive): "
+                    + samplingInterval);
+            return;
+        }
+
         synchronized (mLock) {
             if (samplingInterval != mPeriodicSamplingInterval) {
                 mPeriodicSamplingInterval = samplingInterval;
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index 0650d0af..e4724ff 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -17,6 +17,7 @@
 package com.android.internal.os;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -36,7 +37,7 @@
  * @hide Only for use within the system server.
  */
 public class LooperStats implements Looper.Observer {
-    private static final int TOKEN_POOL_SIZE = 50;
+    private static final int SESSION_POOL_SIZE = 50;
 
     @GuardedBy("mLock")
     private final SparseArray<Entry> mEntries = new SparseArray<>(512);
@@ -78,17 +79,19 @@
         }
 
         DispatchSession session = (DispatchSession) token;
-        Entry entry = getOrCreateEntry(msg);
-        synchronized (entry) {
-            entry.messageCount++;
-            if (session != DispatchSession.NOT_SAMPLED) {
-                entry.recordedMessageCount++;
-                long latency = getElapsedRealtimeMicro() - session.startTimeMicro;
-                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);
+        Entry entry = findEntry(msg, /* allowCreateNew= */session != DispatchSession.NOT_SAMPLED);
+        if (entry != null) {
+            synchronized (entry) {
+                entry.messageCount++;
+                if (session != DispatchSession.NOT_SAMPLED) {
+                    entry.recordedMessageCount++;
+                    long latency = getElapsedRealtimeMicro() - session.startTimeMicro;
+                    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);
+                }
             }
         }
 
@@ -102,7 +105,7 @@
         }
 
         DispatchSession session = (DispatchSession) token;
-        Entry entry = getOrCreateEntry(msg);
+        Entry entry = findEntry(msg, /* allowCreateNew= */true);
         synchronized (entry) {
             entry.exceptionCount++;
         }
@@ -159,24 +162,28 @@
         mSamplingInterval = samplingInterval;
     }
 
-    @NonNull
-    private Entry getOrCreateEntry(Message msg) {
+    @Nullable
+    private Entry findEntry(Message msg, boolean allowCreateNew) {
         final boolean isInteractive = mDeviceState.isScreenInteractive();
         final int id = Entry.idFor(msg, isInteractive);
         Entry entry;
         synchronized (mLock) {
             entry = mEntries.get(id);
             if (entry == null) {
-                if (mEntries.size() >= mEntriesSizeCap) {
-                    // If over the size cap, track totals under a single entry.
+                if (!allowCreateNew) {
+                    return null;
+                } else if (mEntries.size() >= mEntriesSizeCap) {
+                    // If over the size cap track totals under OVERFLOW entry.
                     return mOverflowEntry;
+                } else {
+                    entry = new Entry(msg, isInteractive);
+                    mEntries.put(id, entry);
                 }
-                entry = new Entry(msg, isInteractive);
-                mEntries.put(id, entry);
             }
         }
 
-        if (entry.handler.getClass() != msg.getTarget().getClass()
+        if (entry.workSourceUid != msg.workSourceUid
+                || entry.handler.getClass() != msg.getTarget().getClass()
                 || entry.handler.getLooper().getThread() != msg.getTarget().getLooper().getThread()
                 || entry.isInteractive != isInteractive) {
             // If a hash collision happened, track totals under a single entry.
@@ -186,7 +193,7 @@
     }
 
     private void recycleSession(DispatchSession session) {
-        if (session != DispatchSession.NOT_SAMPLED && mSessionPool.size() < TOKEN_POOL_SIZE) {
+        if (session != DispatchSession.NOT_SAMPLED && mSessionPool.size() < SESSION_POOL_SIZE) {
             mSessionPool.add(session);
         }
     }
@@ -210,6 +217,7 @@
     }
 
     private static class Entry {
+        public final int workSourceUid;
         public final Handler handler;
         public final String messageName;
         public final boolean isInteractive;
@@ -222,12 +230,14 @@
         public long maxCpuUsageMicro;
 
         Entry(Message msg, boolean isInteractive) {
+            this.workSourceUid = msg.workSourceUid;
             this.handler = msg.getTarget();
             this.messageName = handler.getMessageName(msg);
             this.isInteractive = isInteractive;
         }
 
         Entry(String specialEntryName) {
+            this.workSourceUid = Message.UID_NONE;
             this.messageName = specialEntryName;
             this.handler = null;
             this.isInteractive = false;
@@ -245,6 +255,7 @@
 
         static int idFor(Message msg, boolean isInteractive) {
             int result = 7;
+            result = 31 * result + msg.workSourceUid;
             result = 31 * result + msg.getTarget().getLooper().getThread().hashCode();
             result = 31 * result + msg.getTarget().getClass().hashCode();
             result = 31 * result + (isInteractive ? 1231 : 1237);
@@ -258,6 +269,7 @@
 
     /** Aggregated data of Looper message dispatching in the in the current process. */
     public static class ExportedEntry {
+        public final int workSourceUid;
         public final String handlerClassName;
         public final String threadName;
         public final String messageName;
@@ -271,6 +283,7 @@
         public final long maxCpuUsageMicros;
 
         ExportedEntry(Entry entry) {
+            this.workSourceUid = entry.workSourceUid;
             if (entry.handler != null) {
                 this.handlerClassName = entry.handler.getClass().getName();
                 this.threadName = entry.handler.getLooper().getThread().getName();
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/StoragedUidIoStatsReader.java b/core/java/com/android/internal/os/StoragedUidIoStatsReader.java
new file mode 100644
index 0000000..9b03469
--- /dev/null
+++ b/core/java/com/android/internal/os/StoragedUidIoStatsReader.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.internal.os;
+
+import android.os.StrictMode;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+
+/**
+ * Reads /proc/uid_io/stats which has the line format:
+ *
+ * uid: foreground_read_chars foreground_write_chars foreground_read_bytes foreground_write_bytes
+ * background_read_chars background_write_chars background_read_bytes background_write_bytes
+ * foreground_fsync background_fsync
+ *
+ * This provides the number of bytes/chars read/written in foreground/background for each uid.
+ * The file contains a monotonically increasing count of bytes/chars for a single boot.
+ */
+public class StoragedUidIoStatsReader {
+
+    private static final String TAG = StoragedUidIoStatsReader.class.getSimpleName();
+    private static String sUidIoFile = "/proc/uid_io/stats";
+
+    public StoragedUidIoStatsReader() {
+    }
+
+    @VisibleForTesting
+    public StoragedUidIoStatsReader(String file) {
+        sUidIoFile = file;
+    }
+
+    /**
+     * Notifies when new data is available.
+     */
+    public interface Callback {
+
+        /**
+         * Provides data to the client.
+         *
+         * Note: Bytes are I/O events from a storage device. Chars are data requested by syscalls,
+         *   and can be satisfied by caching.
+         */
+        void onUidStorageStats(int uid, long fgCharsRead, long fgCharsWrite, long fgBytesRead,
+                long fgBytesWrite, long bgCharsRead, long bgCharsWrite, long bgBytesRead,
+                long bgBytesWrite, long fgFsync, long bgFsync);
+    }
+
+    /**
+     * Reads the proc file, calling into the callback with raw absolute value of I/O stats
+     * for each UID.
+     *
+     * @param callback The callback to invoke for each line of the proc file.
+     */
+    public void readAbsolute(Callback callback) {
+        final int oldMask = StrictMode.allowThreadDiskReadsMask();
+        File file = new File(sUidIoFile);
+        try (BufferedReader reader = Files.newBufferedReader(file.toPath())) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                String[] fields = TextUtils.split(line, " ");
+                if (fields.length != 11) {
+                    Slog.e(TAG, "Malformed entry in " + sUidIoFile + ": " + line);
+                    continue;
+                }
+                try {
+                    final String uidStr = fields[0];
+                    final int uid = Integer.parseInt(fields[0], 10);
+                    final long fgCharsRead = Long.parseLong(fields[1], 10);
+                    final long fgCharsWrite = Long.parseLong(fields[2], 10);
+                    final long fgBytesRead = Long.parseLong(fields[3], 10);
+                    final long fgBytesWrite = Long.parseLong(fields[4], 10);
+                    final long bgCharsRead = Long.parseLong(fields[5], 10);
+                    final long bgCharsWrite = Long.parseLong(fields[6], 10);
+                    final long bgBytesRead = Long.parseLong(fields[7], 10);
+                    final long bgBytesWrite = Long.parseLong(fields[8], 10);
+                    final long fgFsync = Long.parseLong(fields[9], 10);
+                    final long bgFsync = Long.parseLong(fields[10], 10);
+                    callback.onUidStorageStats(uid, fgCharsRead, fgCharsWrite, fgBytesRead,
+                            fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
+                            fgFsync, bgFsync);
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Could not parse entry in " + sUidIoFile + ": " + e.getMessage());
+                }
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to read " + sUidIoFile + ": " + e.getMessage());
+        } finally {
+            StrictMode.setThreadPolicyMask(oldMask);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 927322e..98b7b5d 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -133,15 +133,16 @@
      * if this is the parent, or -1 on error.
      */
     public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
-          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
-          int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
-          String packageName) {
+            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
+            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
+            String packageName, String[] packagesForUid, String[] visibleVolIds) {
         VM_HOOKS.preFork();
         // Resets nice priority for zygote process.
         resetNicePriority();
         int pid = nativeForkAndSpecialize(
                   uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
-                  fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName);
+                  fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName,
+                  packagesForUid, visibleVolIds);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
             Trace.setTracingEnabled(true, runtimeFlags);
@@ -154,9 +155,9 @@
     }
 
     native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int runtimeFlags,
-          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
-          int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
-          String packageName);
+            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
+            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
+            String packageName, String[] packagesForUid, String[] visibleVolIds);
 
     /**
      * Called to do any initialization before starting an application.
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 06c41d8..4a94ec4 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -241,7 +241,8 @@
         pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                 parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                 parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
-                parsedArgs.instructionSet, parsedArgs.appDataDir, parsedArgs.packageName);
+                parsedArgs.instructionSet, parsedArgs.appDataDir, parsedArgs.packageName,
+                parsedArgs.packagesForUid, parsedArgs.visibleVolIds);
 
         try {
             if (pid == 0) {
@@ -432,6 +433,12 @@
         /** from --package-name */
         String packageName;
 
+        /** from --packages-for-uid */
+        String[] packagesForUid;
+
+        /** from --visible-vols */
+        String[] visibleVolIds;
+
         /**
          * Any args after and including the first non-option arg
          * (or after a '--')
@@ -687,6 +694,10 @@
                         throw new IllegalArgumentException("Duplicate arg specified");
                     }
                     packageName = arg.substring(arg.indexOf('=') + 1);
+                } else if (arg.startsWith("--packages-for-uid=")) {
+                    packagesForUid = arg.substring(arg.indexOf('=') + 1).split(",");
+                } else if (arg.startsWith("--visible-vols=")) {
+                    visibleVolIds = arg.substring(arg.indexOf('=') + 1).split(",");
                 } else {
                     break;
                 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c4214cf..9b8f120 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -141,7 +141,8 @@
     void showShutdownUi(boolean isReboot, String reason);
 
     // Used to show the dialog when BiometricService starts authentication
-    void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver, int type);
+    void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver, int type,
+            boolean requireConfirmation);
     // Used to hide the dialog when a biometric is authenticated
     void onBiometricAuthenticated();
     // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index e48e733..90f2002 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -91,7 +91,8 @@
     void showPinningEscapeToast();
 
     // Used to show the dialog when BiometricService starts authentication
-    void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver, int type);
+    void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver, int type,
+            boolean requireConfirmation);
     // Used to hide the dialog when a biometric is authenticated
     void onBiometricAuthenticated();
     // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
diff --git a/core/java/com/android/internal/util/ContrastColorUtil.java b/core/java/com/android/internal/util/ContrastColorUtil.java
index 1038199..a403c06 100644
--- a/core/java/com/android/internal/util/ContrastColorUtil.java
+++ b/core/java/com/android/internal/util/ContrastColorUtil.java
@@ -523,8 +523,9 @@
     }
 
     public static int resolveAmbientColor(Context context, int notificationColor) {
-        final int resolvedColor = resolveColor(context, notificationColor,
-                true /* defaultBackgroundIsDark */);
+        final int resolvedColor = notificationColor == Notification.COLOR_DEFAULT
+                ? context.getColor(com.android.internal.R.color.notification_default_color_dark)
+                : notificationColor;
 
         int color = resolvedColor;
         color = ContrastColorUtil.ensureTextContrastOnBlack(color);
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/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 543f4a5..dceacda 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -31,6 +31,9 @@
  * applications.
  */
 interface IInputMethodManager {
+    void addClient(in IInputMethodClient client, in IInputContext inputContext,
+            int untrustedDisplayId);
+
     // TODO: Use ParceledListSlice instead
     List<InputMethodInfo> getInputMethodList();
     List<InputMethodInfo> getVrInputMethodList();
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index 7548c22..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,14 +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#inputMethodClientHasFocus(
-         * IInputMethodClient)
+         * @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
@@ -272,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 + ")";
         }
@@ -317,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/jni/Android.bp b/core/jni/Android.bp
index 762b430..c2ca2fc 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -209,6 +209,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,6 +234,7 @@
         "libseccomp_policy",
         "libgrallocusage",
         "libscrypt_static",
+        "libstatssocket",
     ],
 
     shared_libs: [
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 0a25271..c32de0a 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -7,16 +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 "SkDither.h"
-#include "SkUnPreMultiply.h"
 #include "SkStream.h"
 
 #include <binder/Parcel.h>
@@ -28,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>
@@ -326,33 +323,6 @@
     return true;
 }
 
-//////////////////// ToColor procs
-
-static void ToColor_SA8(SkColor dst[], const void* src, int width) {
-    SkASSERT(width > 0);
-    const uint8_t* s = (const uint8_t*)src;
-    do {
-        uint8_t c = *s++;
-        *dst++ = SkColorSetARGB(c, 0, 0, 0);
-    } while (--width != 0);
-}
-
-static void ToF16_SA8(void* dst, const void* src, int width) {
-    SkASSERT(width > 0);
-    uint64_t* d = (uint64_t*)dst;
-    const uint8_t* s = (const uint8_t*)src;
-
-    for (int i = 0; i < width; i++) {
-        uint8_t c = *s++;
-        SkPM4f a;
-        a.fVec[SkPM4f::R] = 0.0f;
-        a.fVec[SkPM4f::G] = 0.0f;
-        a.fVec[SkPM4f::B] = 0.0f;
-        a.fVec[SkPM4f::A] = c / 255.0f;
-        *d++ = a.toF16();
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -417,23 +387,12 @@
     SkImageInfo dstInfo = srcPM.info().makeColorType(dstCT);
     switch (dstCT) {
         case kRGB_565_SkColorType:
-            // copyTo() has never been strict on alpha type.  Here we set the src to opaque to
-            // allow the call to readPixels() to succeed and preserve this lenient behavior.
-            if (kOpaque_SkAlphaType != srcPM.alphaType()) {
-                srcPM = SkPixmap(srcPM.info().makeAlphaType(kOpaque_SkAlphaType), srcPM.addr(),
-                                 srcPM.rowBytes());
-                dstInfo = dstInfo.makeAlphaType(kOpaque_SkAlphaType);
-            }
+            dstInfo = dstInfo.makeAlphaType(kOpaque_SkAlphaType);
             break;
         case kRGBA_F16_SkColorType:
             // The caller does not have an opportunity to pass a dst color space.  Assume that
             // they want linear sRGB.
             dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
-
-            if (!srcPM.colorSpace()) {
-                // Skia needs a color space to convert to F16.  nullptr should be treated as sRGB.
-                srcPM.setColorSpace(SkColorSpace::MakeSRGB());
-            }
             break;
         default:
             break;
@@ -446,57 +405,11 @@
         return false;
     }
 
-    // Skia does not support copying from kAlpha8 to types that are not alpha only.
-    // We will handle this case here.
-    if (kAlpha_8_SkColorType == srcPM.colorType() && kAlpha_8_SkColorType != dstCT) {
-        switch (dstCT) {
-            case kRGBA_8888_SkColorType:
-            case kBGRA_8888_SkColorType: {
-                for (int y = 0; y < src.height(); y++) {
-                    const uint8_t* srcRow = srcPM.addr8(0, y);
-                    uint32_t* dstRow = dst->getAddr32(0, y);
-                    ToColor_SA8(dstRow, srcRow, src.width());
-                }
-                return true;
-            }
-            case kRGB_565_SkColorType: {
-                for (int y = 0; y < src.height(); y++) {
-                    uint16_t* dstRow = dst->getAddr16(0, y);
-                    memset(dstRow, 0, sizeof(uint16_t) * src.width());
-                }
-                return true;
-            }
-            case kRGBA_F16_SkColorType: {
-               for (int y = 0; y < src.height(); y++) {
-                   const uint8_t* srcRow = srcPM.addr8(0, y);
-                   void* dstRow = dst->getAddr(0, y);
-                   ToF16_SA8(dstRow, srcRow, src.width());
-               }
-               return true;
-           }
-            default:
-                return false;
-        }
-    }
-
     SkPixmap dstPM;
     if (!dst->peekPixels(&dstPM)) {
         return false;
     }
 
-    // Skia needs a color space to convert from F16.  nullptr should be treated as sRGB.
-    if (kRGBA_F16_SkColorType == srcPM.colorType() && !dstPM.colorSpace()) {
-        dstPM.setColorSpace(SkColorSpace::MakeSRGB());
-    }
-
-    // readPixels does not support color spaces with parametric transfer functions.  This
-    // works around that restriction when the color spaces are equal.
-    if (kRGBA_F16_SkColorType != dstCT && kRGBA_F16_SkColorType != srcPM.colorType() &&
-            dstPM.colorSpace() == srcPM.colorSpace()) {
-        dstPM.setColorSpace(nullptr);
-        srcPM.setColorSpace(nullptr);
-    }
-
     return srcPM.readPixels(dstPM);
 }
 
@@ -644,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;
@@ -1198,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);
@@ -1210,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(),
@@ -1289,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/pdf/PdfDocument.cpp b/core/jni/android/graphics/pdf/PdfDocument.cpp
index e2dc52b..5f67d30 100644
--- a/core/jni/android/graphics/pdf/PdfDocument.cpp
+++ b/core/jni/android/graphics/pdf/PdfDocument.cpp
@@ -21,11 +21,11 @@
 
 #include "CreateJavaOutputStreamAdaptor.h"
 
-#include "SkDocument.h"
+#include "SkPDFDocument.h"
 #include "SkPicture.h"
 #include "SkPictureRecorder.h"
-#include "SkStream.h"
 #include "SkRect.h"
+#include "SkStream.h"
 
 #include <hwui/Canvas.h>
 
@@ -88,7 +88,7 @@
     }
 
     void write(SkWStream* stream) {
-        sk_sp<SkDocument> document = SkDocument::MakePDF(stream);
+        sk_sp<SkDocument> document = SkPDF::MakeDocument(stream);
         for (unsigned i = 0; i < mPages.size(); i++) {
             PageRecord* page =  mPages[i];
 
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index b163597..a45b493 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -622,13 +622,17 @@
 
 // ---------------------------------------------------------------------------
 
+// The internal format is no longer the same as pixel format, per Table 2 in
+// https://www.khronos.org/registry/OpenGL-Refpages/es3.1/html/glTexImage2D.xhtml
 static int checkInternalFormat(SkColorType colorType, int internalformat,
     int type)
 {
     switch(colorType) {
         case kN32_SkColorType:
             return (type == GL_UNSIGNED_BYTE &&
-                internalformat == GL_RGBA) ? 0 : -1;
+                    internalformat == GL_RGBA) ||
+                (type == GL_UNSIGNED_BYTE &&
+                 internalformat == GL_SRGB8_ALPHA8) ? 0 : -1;
         case kAlpha_8_SkColorType:
             return (type == GL_UNSIGNED_BYTE &&
                 internalformat == GL_ALPHA) ? 0 : -1;
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index eba4c50..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},
@@ -674,7 +702,7 @@
     int ret = 0;
     ret |= RegisterMethodsOrDie(env, "android/graphics/Canvas", gMethods, NELEM(gMethods));
     ret |= RegisterMethodsOrDie(env, "android/graphics/BaseCanvas", gDrawMethods, NELEM(gDrawMethods));
-    ret |= RegisterMethodsOrDie(env, "android/view/RecordingCanvas", gDrawMethods, NELEM(gDrawMethods));
+    ret |= RegisterMethodsOrDie(env, "android/graphics/BaseRecordingCanvas", gDrawMethods, NELEM(gDrawMethods));
     return ret;
 
 }
diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp
index 6f4a58a..58a2379 100644
--- a/core/jni/android_graphics_drawable_VectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp
@@ -130,7 +130,7 @@
 
 static jfloat getRootAlpha(JNIEnv*, jobject, jlong treePtr) {
     VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
-    return tree->stagingProperties()->getRootAlpha();
+    return tree->stagingProperties().getRootAlpha();
 }
 
 static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong fullPathPtr,
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/core/jni/android_hardware_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
new file mode 100644
index 0000000..8ace8da
--- /dev/null
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputApplicationHandle"
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/threads.h>
+
+#include "android_hardware_input_InputApplicationHandle.h"
+
+namespace android {
+
+static struct {
+    jfieldID ptr;
+    jfieldID name;
+    jfieldID dispatchingTimeoutNanos;
+} gInputApplicationHandleClassInfo;
+
+static Mutex gHandleMutex;
+
+
+// --- NativeInputApplicationHandle ---
+
+NativeInputApplicationHandle::NativeInputApplicationHandle(jweak objWeak) :
+        mObjWeak(objWeak) {
+}
+
+NativeInputApplicationHandle::~NativeInputApplicationHandle() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteWeakGlobalRef(mObjWeak);
+}
+
+jobject NativeInputApplicationHandle::getInputApplicationHandleObjLocalRef(JNIEnv* env) {
+    return env->NewLocalRef(mObjWeak);
+}
+
+bool NativeInputApplicationHandle::updateInfo() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject obj = env->NewLocalRef(mObjWeak);
+    if (!obj) {
+        releaseInfo();
+        return false;
+    }
+
+    if (!mInfo) {
+        mInfo = new InputApplicationInfo();
+    }
+
+    jstring nameObj = jstring(env->GetObjectField(obj,
+            gInputApplicationHandleClassInfo.name));
+    if (nameObj) {
+        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
+        mInfo->name = nameStr;
+        env->ReleaseStringUTFChars(nameObj, nameStr);
+        env->DeleteLocalRef(nameObj);
+    } else {
+        mInfo->name = "<null>";
+    }
+
+    mInfo->dispatchingTimeout = env->GetLongField(obj,
+            gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
+
+    env->DeleteLocalRef(obj);
+    return true;
+}
+
+
+// --- Global functions ---
+
+sp<InputApplicationHandle> android_server_InputApplicationHandle_getHandle(
+        JNIEnv* env, jobject inputApplicationHandleObj) {
+    if (!inputApplicationHandleObj) {
+        return NULL;
+    }
+
+    AutoMutex _l(gHandleMutex);
+
+    jlong ptr = env->GetLongField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr);
+    NativeInputApplicationHandle* handle;
+    if (ptr) {
+        handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr);
+    } else {
+        jweak objWeak = env->NewWeakGlobalRef(inputApplicationHandleObj);
+        handle = new NativeInputApplicationHandle(objWeak);
+        handle->incStrong((void*)android_server_InputApplicationHandle_getHandle);
+        env->SetLongField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr,
+                reinterpret_cast<jlong>(handle));
+    }
+    return handle;
+}
+
+
+// --- JNI ---
+
+static void android_server_InputApplicationHandle_nativeDispose(JNIEnv* env, jobject obj) {
+    AutoMutex _l(gHandleMutex);
+
+    jlong ptr = env->GetLongField(obj, gInputApplicationHandleClassInfo.ptr);
+    if (ptr) {
+        env->SetLongField(obj, gInputApplicationHandleClassInfo.ptr, 0);
+
+        NativeInputApplicationHandle* handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr);
+        handle->decStrong((void*)android_server_InputApplicationHandle_getHandle);
+    }
+}
+
+
+static const JNINativeMethod gInputApplicationHandleMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeDispose", "()V",
+            (void*) android_server_InputApplicationHandle_nativeDispose },
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! (var), "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
+
+int register_android_server_InputApplicationHandle(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputApplicationHandle",
+            gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
+    (void) res;  // Faked use when LOG_NDEBUG.
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    jclass clazz;
+    FIND_CLASS(clazz, "com/android/server/input/InputApplicationHandle");
+
+    GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
+            "ptr", "J");
+
+    GET_FIELD_ID(gInputApplicationHandleClassInfo.name, clazz,
+            "name", "Ljava/lang/String;");
+
+    GET_FIELD_ID(gInputApplicationHandleClassInfo.dispatchingTimeoutNanos,
+            clazz,
+            "dispatchingTimeoutNanos", "J");
+
+    return 0;
+}
+
+} /* namespace android */
diff --git a/core/jni/android_hardware_input_InputApplicationHandle.h b/core/jni/android_hardware_input_InputApplicationHandle.h
new file mode 100644
index 0000000..7115611
--- /dev/null
+++ b/core/jni/android_hardware_input_InputApplicationHandle.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
+#define _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
+
+#include <string>
+
+#include <input/InputApplication.h>
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+namespace android {
+
+class NativeInputApplicationHandle : public InputApplicationHandle {
+public:
+    explicit NativeInputApplicationHandle(jweak objWeak);
+    virtual ~NativeInputApplicationHandle();
+
+    jobject getInputApplicationHandleObjLocalRef(JNIEnv* env);
+
+    virtual bool updateInfo();
+
+private:
+    jweak mObjWeak;
+};
+
+
+extern sp<InputApplicationHandle> android_server_InputApplicationHandle_getHandle(
+        JNIEnv* env, jobject inputApplicationHandleObj);
+
+} // namespace android
+
+#endif // _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
new file mode 100644
index 0000000..f4829ad
--- /dev/null
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputWindowHandle"
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/threads.h>
+
+#include <android_view_InputChannel.h>
+#include <android/graphics/Region.h>
+#include <ui/Region.h>
+
+#include "android_hardware_input_InputWindowHandle.h"
+#include "android_hardware_input_InputApplicationHandle.h"
+
+namespace android {
+
+static struct {
+    jfieldID ptr;
+    jfieldID inputApplicationHandle;
+    jfieldID inputChannel;
+    jfieldID name;
+    jfieldID layoutParamsFlags;
+    jfieldID layoutParamsType;
+    jfieldID dispatchingTimeoutNanos;
+    jfieldID frameLeft;
+    jfieldID frameTop;
+    jfieldID frameRight;
+    jfieldID frameBottom;
+    jfieldID scaleFactor;
+    jfieldID touchableRegion;
+    jfieldID visible;
+    jfieldID canReceiveKeys;
+    jfieldID hasFocus;
+    jfieldID hasWallpaper;
+    jfieldID paused;
+    jfieldID layer;
+    jfieldID ownerPid;
+    jfieldID ownerUid;
+    jfieldID inputFeatures;
+    jfieldID displayId;
+} gInputWindowHandleClassInfo;
+
+static Mutex gHandleMutex;
+
+
+// --- NativeInputWindowHandle ---
+
+NativeInputWindowHandle::NativeInputWindowHandle(
+        const sp<InputApplicationHandle>& inputApplicationHandle, jweak objWeak) :
+        InputWindowHandle(inputApplicationHandle),
+        mObjWeak(objWeak) {
+}
+
+NativeInputWindowHandle::~NativeInputWindowHandle() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteWeakGlobalRef(mObjWeak);
+}
+
+jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
+    return env->NewLocalRef(mObjWeak);
+}
+
+bool NativeInputWindowHandle::updateInfo() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject obj = env->NewLocalRef(mObjWeak);
+    if (!obj) {
+        releaseInfo();
+        return false;
+    }
+
+    if (!mInfo) {
+        mInfo = new InputWindowInfo();
+    } else {
+        mInfo->touchableRegion.clear();
+    }
+
+    jobject inputChannelObj = env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.inputChannel);
+    if (inputChannelObj) {
+        mInfo->inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj);
+        env->DeleteLocalRef(inputChannelObj);
+    } else {
+        mInfo->inputChannel.clear();
+    }
+
+    jstring nameObj = jstring(env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.name));
+    if (nameObj) {
+        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
+        mInfo->name = nameStr;
+        env->ReleaseStringUTFChars(nameObj, nameStr);
+        env->DeleteLocalRef(nameObj);
+    } else {
+        mInfo->name = "<null>";
+    }
+
+    mInfo->layoutParamsFlags = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.layoutParamsFlags);
+    mInfo->layoutParamsType = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.layoutParamsType);
+    mInfo->dispatchingTimeout = env->GetLongField(obj,
+            gInputWindowHandleClassInfo.dispatchingTimeoutNanos);
+    mInfo->frameLeft = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameLeft);
+    mInfo->frameTop = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameTop);
+    mInfo->frameRight = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameRight);
+    mInfo->frameBottom = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameBottom);
+    mInfo->scaleFactor = env->GetFloatField(obj,
+            gInputWindowHandleClassInfo.scaleFactor);
+
+    jobject regionObj = env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.touchableRegion);
+    if (regionObj) {
+        SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
+        for (SkRegion::Iterator it(*region); !it.done(); it.next()) {
+            const SkIRect& rect = it.rect();
+            mInfo->addTouchableRegion(Rect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom));
+        }
+        env->DeleteLocalRef(regionObj);
+    }
+
+    mInfo->visible = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.visible);
+    mInfo->canReceiveKeys = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.canReceiveKeys);
+    mInfo->hasFocus = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.hasFocus);
+    mInfo->hasWallpaper = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.hasWallpaper);
+    mInfo->paused = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.paused);
+    mInfo->layer = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.layer);
+    mInfo->ownerPid = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.ownerPid);
+    mInfo->ownerUid = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.ownerUid);
+    mInfo->inputFeatures = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.inputFeatures);
+    mInfo->displayId = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.displayId);
+
+    env->DeleteLocalRef(obj);
+    return true;
+}
+
+
+// --- Global functions ---
+
+sp<NativeInputWindowHandle> android_server_InputWindowHandle_getHandle(
+        JNIEnv* env, jobject inputWindowHandleObj) {
+    if (!inputWindowHandleObj) {
+        return NULL;
+    }
+
+    AutoMutex _l(gHandleMutex);
+
+    jlong ptr = env->GetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr);
+    NativeInputWindowHandle* handle;
+    if (ptr) {
+        handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
+    } else {
+        jobject inputApplicationHandleObj = env->GetObjectField(inputWindowHandleObj,
+                gInputWindowHandleClassInfo.inputApplicationHandle);
+        sp<InputApplicationHandle> inputApplicationHandle =
+                android_server_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
+        env->DeleteLocalRef(inputApplicationHandleObj);
+
+        jweak objWeak = env->NewWeakGlobalRef(inputWindowHandleObj);
+        handle = new NativeInputWindowHandle(inputApplicationHandle, objWeak);
+        handle->incStrong((void*)android_server_InputWindowHandle_getHandle);
+        env->SetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr,
+                reinterpret_cast<jlong>(handle));
+    }
+    return handle;
+}
+
+
+// --- JNI ---
+
+static void android_server_InputWindowHandle_nativeDispose(JNIEnv* env, jobject obj) {
+    AutoMutex _l(gHandleMutex);
+
+    jlong ptr = env->GetLongField(obj, gInputWindowHandleClassInfo.ptr);
+    if (ptr) {
+        env->SetLongField(obj, gInputWindowHandleClassInfo.ptr, 0);
+
+        NativeInputWindowHandle* handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
+        handle->decStrong((void*)android_server_InputWindowHandle_getHandle);
+    }
+}
+
+
+static const JNINativeMethod gInputWindowHandleMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeDispose", "()V",
+            (void*) android_server_InputWindowHandle_nativeDispose },
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! (var), "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
+
+int register_android_server_InputWindowHandle(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputWindowHandle",
+            gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
+    (void) res;  // Faked use when LOG_NDEBUG.
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    jclass clazz;
+    FIND_CLASS(clazz, "com/android/server/input/InputWindowHandle");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz,
+            "ptr", "J");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
+            clazz,
+            "inputApplicationHandle", "Lcom/android/server/input/InputApplicationHandle;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
+            "inputChannel", "Landroid/view/InputChannel;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.name, clazz,
+            "name", "Ljava/lang/String;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz,
+            "layoutParamsFlags", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz,
+            "layoutParamsType", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.dispatchingTimeoutNanos, clazz,
+            "dispatchingTimeoutNanos", "J");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameLeft, clazz,
+            "frameLeft", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameTop, clazz,
+            "frameTop", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameRight, clazz,
+            "frameRight", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameBottom, clazz,
+            "frameBottom", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.scaleFactor, clazz,
+            "scaleFactor", "F");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
+            "touchableRegion", "Landroid/graphics/Region;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
+            "visible", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.canReceiveKeys, clazz,
+            "canReceiveKeys", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.hasFocus, clazz,
+            "hasFocus", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
+            "hasWallpaper", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
+            "paused", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.layer, clazz,
+            "layer", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
+            "ownerPid", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz,
+            "ownerUid", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
+            "inputFeatures", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
+            "displayId", "I");
+    return 0;
+}
+
+} /* namespace android */
diff --git a/core/jni/android_hardware_input_InputWindowHandle.h b/core/jni/android_hardware_input_InputWindowHandle.h
new file mode 100644
index 0000000..2be267e
--- /dev/null
+++ b/core/jni/android_hardware_input_InputWindowHandle.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
+#define _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
+
+#include <input/InputWindow.h>
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+namespace android {
+
+class NativeInputWindowHandle : public InputWindowHandle {
+public:
+    NativeInputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
+            jweak objWeak);
+    virtual ~NativeInputWindowHandle();
+
+    jobject getInputWindowHandleObjLocalRef(JNIEnv* env);
+
+    virtual bool updateInfo();
+
+private:
+    jweak mObjWeak;
+};
+
+
+extern sp<NativeInputWindowHandle> android_server_InputWindowHandle_getHandle(
+        JNIEnv* env, jobject inputWindowHandleObj);
+
+} // namespace android
+
+#endif // _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 6df23f7..a1f2377 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -58,6 +58,11 @@
     int ret;
     int fd;
 
+    if (name == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+
     fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
 
     if (env->ExceptionCheck()) {
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index dfa5de6..b70485d 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -28,6 +28,14 @@
     android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str());
 }
 
+void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, jstring appPref, jboolean devOptIn) {
+    ScopedUtfChars pathChars(env, path);
+    ScopedUtfChars appNameChars(env, appName);
+    ScopedUtfChars appPrefChars(env, appPref);
+    android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(),
+            appPrefChars.c_str(), devOptIn);
+}
+
 void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
     android::NativeLoaderNamespace* appNamespace = android::FindNativeLoaderNamespaceByClassLoader(
         env, classLoader);
@@ -44,6 +52,7 @@
 
 const JNINativeMethod g_methods[] = {
     { "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) },
     { "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_text_LineBreaker.cpp b/core/jni/android_text_LineBreaker.cpp
index dac108e..5439107 100644
--- a/core/jni/android_text_LineBreaker.cpp
+++ b/core/jni/android_text_LineBreaker.cpp
@@ -41,17 +41,6 @@
 
 namespace android {
 
-struct JLineBreaksID {
-    jfieldID breaks;
-    jfieldID widths;
-    jfieldID ascents;
-    jfieldID descents;
-    jfieldID flags;
-};
-
-static jclass gLineBreaks_class;
-static JLineBreaksID gLineBreaks_fieldID;
-
 static inline std::vector<float> jintArrayToFloatVector(JNIEnv* env, jintArray javaArray) {
     if (javaArray == nullptr) {
          return std::vector<float>();
@@ -85,34 +74,7 @@
     return reinterpret_cast<jlong>(nFinish);
 }
 
-static void recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks,
-                        jfloatArray recycleWidths, jfloatArray recycleAscents,
-                        jfloatArray recycleDescents, jintArray recycleFlags,
-                        jint recycleLength, const minikin::LineBreakResult& result) {
-    const size_t nBreaks = result.breakPoints.size();
-    if ((size_t)recycleLength < nBreaks) {
-        // have to reallocate buffers
-        recycleBreaks = env->NewIntArray(nBreaks);
-        recycleWidths = env->NewFloatArray(nBreaks);
-        recycleAscents = env->NewFloatArray(nBreaks);
-        recycleDescents = env->NewFloatArray(nBreaks);
-        recycleFlags = env->NewIntArray(nBreaks);
-
-        env->SetObjectField(recycle, gLineBreaks_fieldID.breaks, recycleBreaks);
-        env->SetObjectField(recycle, gLineBreaks_fieldID.widths, recycleWidths);
-        env->SetObjectField(recycle, gLineBreaks_fieldID.ascents, recycleAscents);
-        env->SetObjectField(recycle, gLineBreaks_fieldID.descents, recycleDescents);
-        env->SetObjectField(recycle, gLineBreaks_fieldID.flags, recycleFlags);
-    }
-    // copy data
-    env->SetIntArrayRegion(recycleBreaks, 0, nBreaks, result.breakPoints.data());
-    env->SetFloatArrayRegion(recycleWidths, 0, nBreaks, result.widths.data());
-    env->SetFloatArrayRegion(recycleAscents, 0, nBreaks, result.ascents.data());
-    env->SetFloatArrayRegion(recycleDescents, 0, nBreaks, result.descents.data());
-    env->SetIntArrayRegion(recycleFlags, 0, nBreaks, result.flags.data());
-}
-
-static jint nComputeLineBreaks(JNIEnv* env, jclass, jlong nativePtr,
+static jlong nComputeLineBreaks(JNIEnv* env, jclass, jlong nativePtr,
         // Inputs
         jcharArray javaText,
         jlong measuredTextPtr,
@@ -122,18 +84,7 @@
         jfloat restWidth,
         jintArray variableTabStops,
         jint defaultTabStop,
-        jint indentsOffset,
-
-        // Outputs
-        jobject recycle,
-        jint recycleLength,
-        jintArray recycleBreaks,
-        jfloatArray recycleWidths,
-        jfloatArray recycleAscents,
-        jfloatArray recycleDescents,
-        jintArray recycleFlags,
-        jfloatArray charWidths) {
-
+        jint indentsOffset) {
     minikin::android::StaticLayoutNative* builder = toNative(nativePtr);
 
     ScopedCharArrayRO text(env, javaText);
@@ -141,14 +92,44 @@
 
     minikin::U16StringPiece u16Text(text.get(), length);
     minikin::MeasuredText* measuredText = reinterpret_cast<minikin::MeasuredText*>(measuredTextPtr);
-    minikin::LineBreakResult result = builder->computeBreaks(
-            u16Text, *measuredText, firstWidth, firstWidthLineCount, restWidth, indentsOffset,
-            tabStops.get(), tabStops.size(), defaultTabStop);
 
-    recycleCopy(env, recycle, recycleBreaks, recycleWidths, recycleAscents, recycleDescents,
-            recycleFlags, recycleLength, result);
+    std::unique_ptr<minikin::LineBreakResult> result =
+          std::make_unique<minikin::LineBreakResult>(builder->computeBreaks(
+                u16Text, *measuredText, firstWidth, firstWidthLineCount, restWidth, indentsOffset,
+                tabStops.get(), tabStops.size(), defaultTabStop));
+    return reinterpret_cast<jlong>(result.release());
+}
 
-    return static_cast<jint>(result.breakPoints.size());
+static jint nGetLineCount(jlong ptr) {
+    return reinterpret_cast<minikin::LineBreakResult*>(ptr)->breakPoints.size();
+}
+
+static jint nGetLineBreakOffset(jlong ptr, jint i) {
+    return reinterpret_cast<minikin::LineBreakResult*>(ptr)->breakPoints[i];
+}
+
+static jfloat nGetLineWidth(jlong ptr, jint i) {
+    return reinterpret_cast<minikin::LineBreakResult*>(ptr)->widths[i];
+}
+
+static jfloat nGetLineAscent(jlong ptr, jint i) {
+    return reinterpret_cast<minikin::LineBreakResult*>(ptr)->ascents[i];
+}
+
+static jfloat nGetLineDescent(jlong ptr, jint i) {
+    return reinterpret_cast<minikin::LineBreakResult*>(ptr)->descents[i];
+}
+
+static jint nGetLineFlag(jlong ptr, jint i) {
+    return reinterpret_cast<minikin::LineBreakResult*>(ptr)->flags[i];
+}
+
+static void nReleaseResult(jlong ptr) {
+    delete reinterpret_cast<minikin::LineBreakResult*>(ptr);
+}
+
+static jlong nGetReleaseResultFunc() {
+    return reinterpret_cast<jlong>(nReleaseResult);
 }
 
 static const JNINativeMethod gMethods[] = {
@@ -166,8 +147,6 @@
     // Regular JNI
     {"nComputeLineBreaks", "("
         "J"  // nativePtr
-
-        // Inputs
         "[C"  // text
         "J"  // MeasuredParagraph ptr.
         "I"  // length
@@ -177,31 +156,20 @@
         "[I"  // variableTabStops
         "I"  // defaultTabStop
         "I"  // indentsOffset
+        ")J", (void*) nComputeLineBreaks},
 
-        // Outputs
-        "Landroid/text/NativeLineBreaker$LineBreaks;"  // recycle
-        "I"  // recycleLength
-        "[I"  // recycleBreaks
-        "[F"  // recycleWidths
-        "[F"  // recycleAscents
-        "[F"  // recycleDescents
-        "[I"  // recycleFlags
-        ")I", (void*) nComputeLineBreaks}
+    // Result accessors, CriticalNatives
+    {"nGetLineCount", "(J)I", (void*)nGetLineCount},
+    {"nGetLineBreakOffset", "(JI)I", (void*)nGetLineBreakOffset},
+    {"nGetLineWidth", "(JI)F", (void*)nGetLineWidth},
+    {"nGetLineAscent", "(JI)F", (void*)nGetLineAscent},
+    {"nGetLineDescent", "(JI)F", (void*)nGetLineDescent},
+    {"nGetLineFlag", "(JI)I", (void*)nGetLineFlag},
+    {"nGetReleaseResultFunc", "()J", (void*)nGetReleaseResultFunc},
 };
 
-int register_android_text_LineBreaker(JNIEnv* env)
-{
-    gLineBreaks_class = MakeGlobalRefOrDie(env,
-            FindClassOrDie(env, "android/text/NativeLineBreaker$LineBreaks"));
-
-    gLineBreaks_fieldID.breaks = GetFieldIDOrDie(env, gLineBreaks_class, "breaks", "[I");
-    gLineBreaks_fieldID.widths = GetFieldIDOrDie(env, gLineBreaks_class, "widths", "[F");
-    gLineBreaks_fieldID.ascents = GetFieldIDOrDie(env, gLineBreaks_class, "ascents", "[F");
-    gLineBreaks_fieldID.descents = GetFieldIDOrDie(env, gLineBreaks_class, "descents", "[F");
-    gLineBreaks_fieldID.flags = GetFieldIDOrDie(env, gLineBreaks_class, "flags", "[I");
-
-    return RegisterMethodsOrDie(env, "android/text/NativeLineBreaker",
-                                gMethods, NELEM(gMethods));
+int register_android_text_LineBreaker(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "android/text/NativeLineBreaker", gMethods, NELEM(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 46b19bd..63b0046 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -444,6 +444,14 @@
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getHeight();
 }
 
+static jboolean android_view_RenderNode_setAllowForceDark(jlong renderNodePtr, jboolean allow) {
+    return SET_AND_DIRTY(setAllowForceDark, allow, RenderNode::GENERIC);
+}
+
+static jboolean android_view_RenderNode_getAllowForceDark(jlong renderNodePtr) {
+    return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getAllowForceDark();
+}
+
 // ----------------------------------------------------------------------------
 // RenderProperties - Animations
 // ----------------------------------------------------------------------------
@@ -465,8 +473,8 @@
 // SurfaceView position callback
 // ----------------------------------------------------------------------------
 
-jmethodID gSurfaceViewPositionUpdateMethod;
-jmethodID gSurfaceViewPositionLostMethod;
+jmethodID gPositionListener_PositionChangedMethod;
+jmethodID gPositionListener_PositionLostMethod;
 
 static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
         jlong renderNodePtr, jobject surfaceview) {
@@ -523,7 +531,7 @@
                 return;
             }
 
-            env->CallVoidMethod(localref, gSurfaceViewPositionLostMethod,
+            env->CallVoidMethod(localref, gPositionListener_PositionLostMethod,
                     info ? info->canvasContext.getFrameNumber() : 0);
             env->DeleteLocalRef(localref);
         }
@@ -547,7 +555,7 @@
                 env->DeleteWeakGlobalRef(mWeakRef);
                 mWeakRef = nullptr;
             } else {
-                env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod,
+                env->CallVoidMethod(localref, gPositionListener_PositionChangedMethod,
                         frameNumber, left, top, right, bottom);
                 env->DeleteLocalRef(localref);
             }
@@ -580,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/SurfaceView;)V", (void*) android_view_RenderNode_requestPositionUpdates },
+    { "nRequestPositionUpdates",   "(JLandroid/view/RenderNode$PositionUpdateListener;)V", (void*) android_view_RenderNode_requestPositionUpdates },
     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
 
 
@@ -664,14 +672,16 @@
     { "nGetPivotY",                "(J)F",  (void*) android_view_RenderNode_getPivotY },
     { "nGetWidth",                 "(J)I",  (void*) android_view_RenderNode_getWidth },
     { "nGetHeight",                "(J)I",  (void*) android_view_RenderNode_getHeight },
+    { "nSetAllowForceDark",        "(JZ)Z", (void*) android_view_RenderNode_setAllowForceDark },
+    { "nGetAllowForceDark",        "(J)Z",  (void*) android_view_RenderNode_getAllowForceDark },
 };
 
 int register_android_view_RenderNode(JNIEnv* env) {
-    jclass clazz = FindClassOrDie(env, "android/view/SurfaceView");
-    gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz,
-            "updateSurfacePosition_renderWorker", "(JIIII)V");
-    gSurfaceViewPositionLostMethod = GetMethodIDOrDie(env, clazz,
-            "surfacePositionLost_uiRtSync", "(J)V");
+    jclass clazz = FindClassOrDie(env, "android/view/RenderNode$PositionUpdateListener");
+    gPositionListener_PositionChangedMethod = GetMethodIDOrDie(env, clazz,
+            "positionChanged", "(JIIII)V");
+    gPositionListener_PositionLostMethod = GetMethodIDOrDie(env, clazz,
+            "positionLost", "(J)V");
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 743b9f6..2e1e130 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -157,23 +157,17 @@
     return Rect(left, top, right, bottom);
 }
 
-static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
+static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
         jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
-        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
-        int rotation) {
+        bool useIdentityTransform, int rotation) {
     sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
     if (displayToken == NULL) {
         return NULL;
     }
     Rect sourceCrop = rectFromObj(env, sourceCropObj);
-    if (allLayers) {
-        minLayer = INT32_MIN;
-        maxLayer = INT32_MAX;
-    }
     sp<GraphicBuffer> buffer;
-    status_t res = ScreenshotClient::capture(displayToken,
-            sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform,
-            rotation, &buffer);
+    status_t res = ScreenshotClient::capture(displayToken, sourceCrop, width, height,
+            useIdentityTransform, rotation, &buffer);
     if (res != NO_ERROR) {
         return NULL;
     }
@@ -187,100 +181,6 @@
             (jlong)buffer.get());
 }
 
-static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
-        jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
-        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
-        int rotation) {
-    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
-    if (displayToken == NULL) {
-        return NULL;
-    }
-
-    Rect sourceCrop = rectFromObj(env, sourceCropObj);
-
-    std::unique_ptr<ScreenshotClient> screenshot(new ScreenshotClient());
-    status_t res;
-    if (allLayers) {
-        minLayer = INT32_MIN;
-        maxLayer = INT32_MAX;
-    }
-
-    sp<GraphicBuffer> buffer;
-    res = ScreenshotClient::capture(displayToken, sourceCrop, width, height,
-        minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation), &buffer);
-    if (res != NO_ERROR) {
-        return NULL;
-    }
-
-    SkColorType colorType;
-    SkAlphaType alphaType;
-
-    PixelFormat format = buffer->getPixelFormat();
-    switch (format) {
-        case PIXEL_FORMAT_RGBX_8888: {
-            colorType = kRGBA_8888_SkColorType;
-            alphaType = kOpaque_SkAlphaType;
-            break;
-        }
-        case PIXEL_FORMAT_RGBA_8888: {
-            colorType = kRGBA_8888_SkColorType;
-            alphaType = kPremul_SkAlphaType;
-            break;
-        }
-        case PIXEL_FORMAT_RGBA_FP16: {
-            colorType = kRGBA_F16_SkColorType;
-            alphaType = kPremul_SkAlphaType;
-            break;
-        }
-        case PIXEL_FORMAT_RGB_565: {
-            colorType = kRGB_565_SkColorType;
-            alphaType = kOpaque_SkAlphaType;
-            break;
-        }
-        default: {
-            return NULL;
-        }
-    }
-
-    SkImageInfo info = SkImageInfo::Make(buffer->getWidth(), buffer->getHeight(),
-                                         colorType, alphaType,
-                                         SkColorSpace::MakeSRGB());
-
-    auto bitmap = sk_sp<Bitmap>(new Bitmap(buffer.get(), info));
-    return bitmap::createBitmap(env, bitmap.release(),
-                                android::bitmap::kBitmapCreateFlag_Premultiplied, NULL);
-}
-
-static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
-        jobject surfaceObj, jobject sourceCropObj, jint width, jint height,
-        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
-    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
-    if (displayToken == NULL) {
-        return;
-    }
-
-    sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
-    if (consumer == NULL) {
-        return;
-    }
-
-    Rect sourceCrop;
-    if (sourceCropObj != NULL) {
-        sourceCrop = rectFromObj(env, sourceCropObj);
-    }
-
-    if (allLayers) {
-        minLayer = INT32_MIN;
-        maxLayer = INT32_MAX;
-    }
-
-    sp<GraphicBuffer> buffer;
-    ScreenshotClient::capture(displayToken, sourceCrop, width, height, minLayer, maxLayer,
-                              useIdentityTransform, 0, &buffer);
-
-    Surface::attachAndQueueBuffer(consumer.get(), buffer);
-}
-
 static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
         jobject sourceCropObj, jfloat frameScale) {
 
@@ -439,6 +339,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) {
@@ -919,10 +830,6 @@
             (void*)nativeDestroy },
     {"nativeDisconnect", "(J)V",
             (void*)nativeDisconnect },
-    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
-            (void*)nativeScreenshotBitmap },
-    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
-            (void*)nativeScreenshot },
     {"nativeCreateTransaction", "()J",
             (void*)nativeCreateTransaction },
     {"nativeApplyTransaction", "(JZ)V",
@@ -953,6 +860,8 @@
             (void*)nativeSetColor },
     {"nativeSetMatrix", "(JJFFFF)V",
             (void*)nativeSetMatrix },
+    {"nativeSetColorTransform", "(JJ[F[F)V",
+            (void*)nativeSetColorTransform },
     {"nativeSetFlags", "(JJII)V",
             (void*)nativeSetFlags },
     {"nativeSetWindowCrop", "(JJIIII)V",
@@ -1013,9 +922,8 @@
             (void*)nativeDestroyInTransaction },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle },
-    {"nativeScreenshotToBuffer",
-     "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;",
-     (void*)nativeScreenshotToBuffer },
+    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZI)Landroid/graphics/GraphicBuffer;",
+            (void*)nativeScreenshot },
     {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
             (void*)nativeCaptureLayers },
 };
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 3c59bd1..7a5b604 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -1064,6 +1064,12 @@
     proxy->allocateBuffers(surface);
 }
 
+static void android_view_ThreadedRenderer_setForceDark(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jboolean enable) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    proxy->setForceDark(enable);
+}
+
 // ----------------------------------------------------------------------------
 // FrameMetricsObserver
 // ----------------------------------------------------------------------------
@@ -1177,6 +1183,7 @@
     { "nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess },
     { "nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority },
     { "nAllocateBuffers", "(JLandroid/view/Surface;)V", (void*)android_view_ThreadedRenderer_allocateBuffers },
+    { "nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark },
 };
 
 static JavaVM* mJvm = nullptr;
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 c15b7ee..109e65c 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -285,10 +285,6 @@
 static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path,
                                   jint limitUid, jobjectArray limitIfacesObj, jint limitTag,
                                   jboolean useBpfStats) {
-    ScopedUtfChars path8(env, path);
-    if (path8.c_str() == NULL) {
-        return -1;
-    }
 
     std::vector<std::string> limitIfaces;
     if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
@@ -308,6 +304,11 @@
         if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0)
             return -1;
     } else {
+        ScopedUtfChars path8(env, path);
+        if (path8.c_str() == NULL) {
+            ALOGE("the qtaguid legacy path is invalid: %s", path8.c_str());
+            return -1;
+        }
         if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag,
                                          limitUid, path8.c_str()) < 0)
             return -1;
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 364393e..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"
@@ -382,11 +383,10 @@
     return 0;
 }
 
-static bool createPkgSandbox(uid_t uid, const char* package_name, std::string& pkg_sandbox_dir,
-        std::string* error_msg) {
+static bool createPkgSandbox(uid_t uid, const std::string& package_name, std::string* error_msg) {
     // Create /mnt/user/0/package/<package-name>
     userid_t user_id = multiuser_get_user_id(uid);
-    StringAppendF(&pkg_sandbox_dir, "/%d", user_id);
+    std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
     if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) {
         *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str());
         return false;
@@ -396,7 +396,7 @@
         *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str());
         return false;
     }
-    StringAppendF(&pkg_sandbox_dir, "/%s", package_name);
+    StringAppendF(&pkg_sandbox_dir, "/%s", package_name.c_str());
     if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0755, uid, uid) != 0) {
         *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str());
         return false;
@@ -404,10 +404,51 @@
     return true;
 }
 
+static bool mountPkgSpecificDir(const std::string& mntSourceRoot,
+        const std::string& mntTargetRoot, const std::string& packageName,
+        const char* dirName, std::string* error_msg) {
+    std::string mntSourceDir = StringPrintf("%s/Android/%s/%s",
+            mntSourceRoot.c_str(), dirName, packageName.c_str());
+    std::string mntTargetDir = StringPrintf("%s/Android/%s/%s",
+            mntTargetRoot.c_str(), dirName, packageName.c_str());
+    if (TEMP_FAILURE_RETRY(mount(mntSourceDir.c_str(), mntTargetDir.c_str(),
+            nullptr, MS_BIND | MS_REC, nullptr)) == -1) {
+        *error_msg = CREATE_ERROR("Failed to mount %s to %s: %s",
+                mntSourceDir.c_str(), mntTargetDir.c_str(), strerror(errno));
+        return false;
+    }
+    if (TEMP_FAILURE_RETRY(mount(nullptr, mntTargetDir.c_str(),
+            nullptr, MS_SLAVE | MS_REC, nullptr)) == -1) {
+        *error_msg = CREATE_ERROR("Failed to set MS_SLAVE for %s", mntTargetDir.c_str());
+        return false;
+    }
+    return true;
+}
+
+static bool preparePkgSpecificDirs(const std::vector<std::string>& packageNames,
+        const std::vector<std::string>& volumeLabels, userid_t userId, std::string* error_msg) {
+    for (auto& label : volumeLabels) {
+        std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str());
+        std::string mntTarget = StringPrintf("/storage/%s", label.c_str());
+        if (label == "emulated") {
+            StringAppendF(&mntSource, "/%d", userId);
+            StringAppendF(&mntTarget, "/%d", userId);
+        }
+        for (auto& package : packageNames) {
+            mountPkgSpecificDir(mntSource, mntTarget, package, "data", error_msg);
+            mountPkgSpecificDir(mntSource, mntTarget, package, "media", error_msg);
+            mountPkgSpecificDir(mntSource, mntTarget, package, "obb", error_msg);
+        }
+    }
+    return true;
+}
+
 // Create a private mount namespace and bind mount appropriate emulated
 // storage for the given user.
 static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
-        bool force_mount_namespace, std::string* error_msg, const char* package_name) {
+        bool force_mount_namespace, std::string* error_msg, const std::string& package_name,
+        const std::vector<std::string>& packages_for_uid,
+        const std::vector<std::string>& visible_vol_ids) {
     // See storage config details at http://source.android.com/tech/storage/
 
     String8 storageSource;
@@ -459,12 +500,25 @@
                 return false;
             }
         } else {
-            if (package_name == nullptr) {
+            if (package_name.empty()) {
                 return true;
             }
-            std::string pkgSandboxDir("/mnt/user");
-            if (!createPkgSandbox(uid, package_name, pkgSandboxDir, error_msg)) {
-                return false;
+            userid_t user_id = multiuser_get_user_id(uid);
+            std::string pkgSandboxDir = StringPrintf("/mnt/user/%d/package/%s",
+                    user_id, package_name.c_str());
+            struct stat sb;
+            bool sandboxAlreadyCreated = true;
+            if (TEMP_FAILURE_RETRY(lstat(pkgSandboxDir.c_str(), &sb)) == -1) {
+                if (errno == ENOENT) {
+                    ALOGD("Sandbox not yet created for %s", pkgSandboxDir.c_str());
+                    sandboxAlreadyCreated = false;
+                    if (!createPkgSandbox(uid, package_name, error_msg)) {
+                        return false;
+                    }
+                } else {
+                    ALOGE("Failed to lstat %s", pkgSandboxDir.c_str());
+                    return false;
+                }
             }
             if (TEMP_FAILURE_RETRY(mount(pkgSandboxDir.c_str(), "/storage",
                     nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
@@ -472,6 +526,15 @@
                         pkgSandboxDir.c_str(), strerror(errno));
                 return false;
             }
+            // If the sandbox was already created by vold, only then set up the bind mounts for
+            // pkg specific directories. Otherwise, leave as is and bind mounts will be taken
+            // care of by vold later.
+            if (sandboxAlreadyCreated) {
+                if (!preparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
+                        user_id, error_msg)) {
+                    return false;
+                }
+            }
         }
     } else {
         if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
@@ -611,7 +674,8 @@
                              jlong permittedCapabilities, jlong effectiveCapabilities,
                              jint mount_external, jstring java_se_info, jstring java_se_name,
                              bool is_system_server, bool is_child_zygote, jstring instructionSet,
-                             jstring dataDir, jstring packageName) {
+                             jstring dataDir, jstring packageName, jobjectArray packagesForUid,
+                             jobjectArray visibleVolIds) {
   std::string error_msg;
 
   auto fail_fn = [env, java_se_name, is_system_server](const std::string& msg)
@@ -661,17 +725,33 @@
     ALOGW("Native bridge will not be used because dataDir == NULL.");
   }
 
-  ScopedUtfChars* package_name = nullptr;
-  const char* package_name_c_str = nullptr;
+  std::string package_name_str("");
   if (packageName != nullptr) {
-    package_name = new ScopedUtfChars(env, packageName);
-    package_name_c_str = package_name->c_str();
+    ScopedUtfChars package(env, packageName);
+    package_name_str = package.c_str();
   } else if (is_system_server) {
-    package_name_c_str = "android";
+    package_name_str = "android";
+  }
+  std::vector<std::string> packages_for_uid;
+  if (packagesForUid != nullptr) {
+    jsize count = env->GetArrayLength(packagesForUid);
+    for (jsize i = 0; i < count; ++i) {
+      jstring package_for_uid = (jstring) env->GetObjectArrayElement(packagesForUid, i);
+      ScopedUtfChars package(env, package_for_uid);
+      packages_for_uid.push_back(package.c_str());
+    }
+  }
+  std::vector<std::string> visible_vol_ids;
+  if (visibleVolIds != nullptr) {
+    jsize count = env->GetArrayLength(visibleVolIds);
+    for (jsize i = 0; i < count; ++i) {
+      jstring visible_vol_id = (jstring) env->GetObjectArrayElement(visibleVolIds, i);
+      ScopedUtfChars vol(env, visible_vol_id);
+      visible_vol_ids.push_back(vol.c_str());
+    }
   }
   bool success = MountEmulatedStorage(uid, mount_external, use_native_bridge, &error_msg,
-      package_name_c_str);
-  delete package_name;
+      package_name_str, packages_for_uid, visible_vol_ids);
   if (!success) {
     ALOGW("Failed to mount emulated storage: %s (%s)", error_msg.c_str(), strerror(errno));
     if (errno == ENOTCONN || errno == EROFS) {
@@ -853,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;
 
@@ -936,7 +1017,8 @@
         jint runtime_flags, jobjectArray rlimits,
         jint mount_external, jstring se_info, jstring se_name,
         jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote,
-        jstring instructionSet, jstring appDataDir, jstring packageName) {
+        jstring instructionSet, jstring appDataDir, jstring packageName,
+        jobjectArray packagesForUid, jobjectArray visibleVolIds) {
     jlong capabilities = 0;
 
     // Grant CAP_WAKE_ALARM to the Bluetooth process.
@@ -989,7 +1071,8 @@
       SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                        capabilities, capabilities,
                        mount_external, se_info, se_name, false,
-                       is_child_zygote == JNI_TRUE, instructionSet, appDataDir, packageName);
+                       is_child_zygote == JNI_TRUE, instructionSet, appDataDir, packageName,
+                       packagesForUid, visibleVolIds);
     }
     return pid;
 }
@@ -1003,7 +1086,7 @@
       SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                        permittedCapabilities, effectiveCapabilities,
                        MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true,
-                       false, NULL, NULL, nullptr);
+                       false, NULL, NULL, nullptr, nullptr, nullptr);
   } else if (pid > 0) {
       // The zygote process checks whether the child process has died or not.
       ALOGI("System server process %d has been created", pid);
@@ -1084,7 +1167,7 @@
     { "nativeSecurityInit", "()V",
       (void *) com_android_internal_os_Zygote_nativeSecurityInit },
     { "nativeForkAndSpecialize",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
+      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)I",
       (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
     { "nativeForkSystemServer", "(II[II[[IJJ)I",
       (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
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/internal/powerprofile.proto b/core/proto/android/internal/powerprofile.proto
new file mode 100644
index 0000000..9dd5e7e
--- /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 = 41;
+
+    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 = 29;
+
+    optional double radio_on = 30;
+
+    optional double radio_scanning = 31;
+
+    optional double radio_active = 32;
+
+    optional double screen_full = 33;
+
+    optional double audio = 34;
+
+    optional double video = 35;
+
+    optional double flashlight = 36;
+
+    optional double memory = 37;
+
+    optional double camera = 38;
+
+    optional double wifi_batched_scan = 39;
+
+    optional double battery_capacity = 40;
+}
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index f9f725a..a02602e 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -397,6 +397,9 @@
         // 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;
     }
     optional Gpu gpu = 59;
 
@@ -739,6 +742,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/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 9d5f0bc..ab50ad1 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -130,6 +130,13 @@
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
     optional bool keyguard_showing = 1;
+    repeated KeyguardOccludedProto keyguard_occluded_states= 2;
+}
+
+message KeyguardOccludedProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 display_id = 1;
     optional bool keyguard_occluded = 2;
 }
 
diff --git a/core/proto/android/server/backup_chunks_metadata.proto b/core/proto/android/server/backup_chunks_metadata.proto
new file mode 100644
index 0000000..a375f02
--- /dev/null
+++ b/core/proto/android/server/backup_chunks_metadata.proto
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.backup.encryption.chunk;
+
+option java_outer_classname = "ChunksMetadataProto";
+
+// Cipher type with which the chunks are encrypted. For now we only support AES/GCM/NoPadding, but
+// this is for backwards-compatibility in case we need to change the default Cipher in the future.
+enum CipherType {
+    UNKNOWN_CIPHER_TYPE = 0;
+    // Chunk is prefixed with a 12-byte nonce. The tag length is 16 bytes.
+    AES_256_GCM = 1;
+}
+
+// Checksum type with which the plaintext is verified.
+enum ChecksumType {
+    UNKNOWN_CHECKSUM_TYPE = 0;
+    SHA_256 = 1;
+}
+
+enum ChunkOrderingType {
+    CHUNK_ORDERING_TYPE_UNSPECIFIED = 0;
+    // The chunk ordering contains a list of the start position of each chunk in the encrypted file,
+    // ordered as in the plaintext file. This allows us to recreate the original plaintext file
+    // during decryption. We use this mode for full backups where the order of the data in the file
+    // is important.
+    EXPLICIT_STARTS = 1;
+    // The chunk ordering does not contain any start positions, and instead each encrypted chunk in
+    // the backup file is prefixed with its length. This allows us to decrypt each chunk but does
+    // not give any information about the order. However, we use this mode for key value backups
+    // where the order does not matter.
+    INLINE_LENGTHS = 2;
+}
+
+// Chunk entry (for local state)
+message Chunk {
+    // SHA-256 MAC of the plaintext of the chunk
+    optional bytes hash = 1;
+    // Number of bytes in encrypted chunk
+    optional int32 length = 2;
+}
+
+// List of the chunks in the blob, along with the length of each chunk. From this is it possible to
+// extract individual chunks. (i.e., start position is equal to the sum of the lengths of all
+// preceding chunks.)
+//
+// This is local state stored on the device. It is never sent to the backup server. See
+// ChunkOrdering for how the device restores the chunks in the correct order.
+// Next tag : 6
+message ChunkListing {
+    repeated Chunk chunks = 1;
+
+    // Cipher algorithm with which the chunks are encrypted.
+    optional CipherType cipher_type = 2;
+
+    // Defines the type of chunk order used to encode the backup file on the server, so that we can
+    // consistently use the same type between backups. If unspecified this backup file was created
+    // before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS.
+    optional ChunkOrderingType chunk_ordering_type = 5;
+
+    // The document ID returned from Scotty server after uploading the blob associated with this
+    // listing. This needs to be sent when uploading new diff scripts.
+    optional string document_id = 3;
+
+    // Fingerprint mixer salt used for content defined chunking. This is randomly generated for each
+    // package during the initial non-incremental backup and reused for incremental backups.
+    optional bytes fingerprint_mixer_salt = 4;
+}
+
+// Ordering information about plaintext and checksum. This is used on restore to reconstruct the
+// blob in its correct order. (The chunk order is randomized so as to give the server less
+// information about which parts of the backup are changing over time.) This proto is encrypted
+// before being uploaded to the server, with a key unknown to the server.
+message ChunkOrdering {
+    // For backups where ChunksMetadata#chunk_ordering_type = EXPLICIT STARTS:
+    // Ordered start positions of chunks. i.e., the file is the chunk starting at this position,
+    // followed by the chunk starting at this position, followed by ... etc. You can compute the
+    // lengths of the chunks by sorting this list then looking at the start position of the next
+    // chunk after the chunk you care about. This is guaranteed to work as all chunks are
+    // represented in this list.
+    //
+    // For backups where ChunksMetadata#chunk_ordering_type = INLINE_LENGTHS:
+    // This field is unused. See ChunkOrderingType#INLINE_LENGTHS.
+    repeated int32 starts = 1 [packed = true];
+
+    // Checksum of plaintext content. (i.e., in correct order.)
+    //
+    // Each chunk also has a MAC, as generated by GCM, so this is NOT Mac-then-Encrypt, which has
+    // security implications. This is an additional checksum to verify that once the chunks have
+    // been reordered, that the file matches the expected plaintext. This prevents the device
+    // restoring garbage data in case of a mismatch between the ChunkOrdering and the backup blob.
+    optional bytes checksum = 2;
+}
+
+// Additional metadata about a backup blob that needs to be synced to the server. This is used on
+// restore to reconstruct the blob in its correct order. (The chunk order is randomized so as to
+// give the server less information about which parts of the backup are changing over time.) This
+// data structure is only ever uploaded to the server encrypted with a key unknown to the server.
+// Next tag : 6
+message ChunksMetadata {
+    // Cipher algorithm with which the chunk listing and chunks are encrypted.
+    optional CipherType cipher_type = 1;
+
+    // Defines the type of chunk order this metadata contains. If unspecified this backup file was
+    // created before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS.
+    optional ChunkOrderingType chunk_ordering_type = 5
+    [default = CHUNK_ORDERING_TYPE_UNSPECIFIED];
+
+    // Encrypted bytes of ChunkOrdering
+    optional bytes chunk_ordering = 2;
+
+    // The type of algorithm used for the checksum of the plaintext. (See ChunkOrdering.) This is
+    // for forwards compatibility in case we change the algorithm in the future. For now, always
+    // SHA-256.
+    optional ChecksumType checksum_type = 3;
+
+    // This used to be the plaintext tertiary key. No longer used.
+    reserved 4;
+}
\ No newline at end of file
diff --git a/core/proto/android/server/usagestatsservice.proto b/core/proto/android/server/usagestatsservice.proto
new file mode 100644
index 0000000..941c81f
--- /dev/null
+++ b/core/proto/android/server/usagestatsservice.proto
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.usage;
+import "frameworks/base/core/proto/android/content/configuration.proto";
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+
+message IntervalStatsProto {
+  message StringPool {
+    optional int32 size = 1;
+    repeated string strings = 2;
+  }
+
+  message CountAndTime {
+    optional int32 count = 1;
+    optional int64 time_ms = 2;
+  }
+
+  // Stores the relevant information from a UsageStats
+  message UsageStats {
+    message ChooserAction {
+      message CategoryCount {
+        optional string name = 1;
+        optional int32 count = 3;
+      }
+      optional string name = 1;
+      repeated CategoryCount counts = 3;
+    }
+    optional string package = 1;
+    // package_index contains the index + 1 of the package name in the string pool
+    optional int32 package_index = 2;
+    optional int64 last_time_active_ms = 3;
+    optional int64 total_time_active_ms = 4;
+    optional int32 last_event = 5;
+    optional int32 app_launch_count = 6;
+    repeated ChooserAction chooser_actions = 7;
+  }
+
+  // Stores the relevant information an IntervalStats will have about a Configuration
+  message Configuration {
+    optional .android.content.ConfigurationProto config = 1;
+    optional int64 last_time_active_ms = 2;
+    optional int64 total_time_active_ms = 3;
+    optional int32 count = 4;
+    optional bool active = 5;
+  }
+
+  // Stores the relevant information from a UsageEvents.Event
+  message Event {
+    optional string package = 1;
+    // package_index contains the index + 1 of the package name in the string pool
+    optional int32 package_index = 2;
+    optional string class = 3;
+    // class_index contains the index + 1 of the class name in the string pool
+    optional int32 class_index = 4;
+    optional int64 time_ms = 5;
+    optional int32 flags = 6;
+    optional int32 type = 7;
+    optional .android.content.ConfigurationProto config = 8;
+    optional string shortcut_id = 9;
+    optional int32 standby_bucket = 11;
+    optional string notification_channel = 12;
+    // notification_channel_index contains the index + 1 of the channel name in the string pool
+    optional int32 notification_channel_index = 13;
+  }
+
+  // The following fields contain supplemental data used to build IntervalStats, such as a string
+  // pool.
+  optional int64 end_time_ms = 1;
+  // stringpool contains all the package and class names used by UsageStats and Event
+  // They will hold a number that is equal to the index + 1 of their string in the pool
+  optional StringPool stringpool = 2;
+
+  // The following fields contain aggregated usage stats data
+  optional CountAndTime interactive = 10;
+  optional CountAndTime non_interactive = 11;
+  optional CountAndTime keyguard_shown = 12;
+  optional CountAndTime keyguard_hidden = 13;
+
+  // The following fields contain listed usage stats data
+  repeated UsageStats packages = 20;
+  repeated Configuration configurations = 21;
+  repeated Event event_log = 22;
+}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 1257336..c1c86f0 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -157,6 +157,8 @@
     optional int32 rotation = 11;
     optional ScreenRotationAnimationProto screen_rotation_animation = 12;
     optional DisplayFramesProto display_frames = 13;
+    optional int32 surface_size = 14;
+    optional string focused_app = 15;
 }
 
 /* represents DisplayFrames */
@@ -211,6 +213,8 @@
     optional .android.graphics.RectProto bounds = 5;
     optional .android.graphics.RectProto temp_inset_bounds = 6;
     optional bool defer_removal = 7;
+    optional int32 surface_width = 8;
+    optional int32 surface_height = 9;
 }
 
 /* represents AppWindowToken */
diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto
index 8836c2e..c08d7ca 100644
--- a/core/proto/android/service/notification.proto
+++ b/core/proto/android/service/notification.proto
@@ -201,6 +201,9 @@
     optional ConditionProto condition = 9;
     optional android.content.ComponentNameProto component = 10;
     optional ZenPolicyProto zenPolicy = 11;
+
+    // Indicates whether this ZenRule has been modified after its initial creation
+    optional bool modified = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
 }
 
 // A dump from com.android.server.notification.ZenModeHelper.
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 1df3f7f..f3f012d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -615,6 +615,8 @@
     <protected-broadcast android:name="com.android.server.jobscheduler.FORCE_IDLE" />
     <protected-broadcast android:name="com.android.server.jobscheduler.UNFORCE_IDLE" />
 
+    <protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -939,7 +941,6 @@
          Requesting this by itself is not sufficient to give you
          location access.
          <p>Protection level: dangerous
-         @hide
     -->
     <permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
         android:permissionGroup="android.permission-group.LOCATION"
@@ -1099,7 +1100,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
     -->
@@ -1184,9 +1185,9 @@
         android:priority="700" />
 
     <!-- Required to be able to access the camera device.
-         <p>This will automatically enforce the <a
-         href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
-         <uses-feature>}</a> manifest element for <em>all</em> camera features.
+         <p>This will automatically enforce the
+         <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
+         uses-feature</a> manifest element for <em>all</em> camera features.
          If you do not require all camera features or can properly operate if a camera
          is not available, then you must modify your manifest as appropriate in order to
          install on devices that don't support all camera features.</p>
@@ -1931,6 +1932,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
@@ -3405,6 +3413,12 @@
    <permission android:name="android.permission.DEVICE_POWER"
         android:protectionLevel="signature" />
 
+    <!-- Allows toggling battery saver on the system.
+         Superseded by DEVICE_POWER permission. @hide @SystemApi
+    -->
+    <permission android:name="android.permission.POWER_SAVER"
+        android:protectionLevel="signature|privileged" />
+
    <!-- Allows access to the PowerManager.userActivity function.
    <p>Not for use by third-party applications. @hide @SystemApi -->
     <permission android:name="android.permission.USER_ACTIVITY"
@@ -4136,6 +4150,21 @@
     <permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS"
                 android:protectionLevel="signature" />
 
+    <!-- @hide Permission that protects the
+        {@link android.provider.Telephony.Intents#ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
+        broadcast -->
+    <permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE"
+        android:protectionLevel="signature" />
+
+    <!-- A subclass of {@link android.app.SmsAppService} must be protected with this permission. -->
+    <permission android:name="android.permission.BIND_SMS_APP_SERVICE"
+        android:protectionLevel="signature" />
+
+    <!-- @hide Permission that allows background clipboard access.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.READ_CLIPBOARD_IN_BACKGROUND"
+        android:protectionLevel="signature" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
@@ -4451,14 +4480,6 @@
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
 
-        <service android:name="com.android.internal.backup.LocalTransportService"
-                android:permission="android.permission.CONFIRM_FULL_BACKUP"
-                android:exported="false">
-            <intent-filter>
-                <action android:name="android.backup.TRANSPORT_HOST" />
-            </intent-filter>
-        </service>
-
         <service android:name="com.android.server.MountServiceIdler"
                  android:exported="true"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
diff --git a/core/res/res/drawable/ic_ab_back_material_settings.xml b/core/res/res/drawable/ic_ab_back_material_settings.xml
index 7325a41..938e36d 100644
--- a/core/res/res/drawable/ic_ab_back_material_settings.xml
+++ b/core/res/res/drawable/ic_ab_back_material_settings.xml
@@ -18,11 +18,12 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
         android:autoMirrored="true"
-        android:tint="?attr/colorControlNormal">
+        android:tint="?attr/colorControlNormal"
+        android:viewportHeight="24"
+        android:viewportWidth="24">
     <path
         android:fillColor="@color/white"
-        android:pathData="M20,11H7.62l4.88,-4.88a0.996,0.996 0,1 0,-1.41 -1.41l-6.94,6.94c-0.2,0.2 -0.2,0.51 0,0.71l6.94,6.94a0.996,0.996 0,1 0,1.41 -1.41L7.62,13H20c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1z"/>
+        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8l8,8l1.41,-1.41L7.83,13H20V11z"/>
 </vector>
+
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index c2c9254..5028150 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Probleem om Wi-Fi-oproepe by jou diensverskaffer te registreer: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi-oproep"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-oproepe"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-oproep"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>-WLAN-oproep"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-oproepe | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>-VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Af"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Verkies Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Verkies mobiel"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nie herken nie"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Vingerafdruk is gestaaf"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Gesig is gestaaf"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Gesig is gestaaf; druk asseblief bevestig"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Vingerafdrukhardeware is nie beskikbaar nie."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Vingerafdruk kan nie gestoor word nie. Verwyder asseblief \'n bestaande vingerafdruk."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vingerafdrukuittelling is bereik. Probeer weer."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Gesiguittelling is bereik. Probeer weer."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Gesig kan nie geberg word nie."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Gesighandeling is gekanselleer."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Gesigstawing is deur gebruiker gekanselleer."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Te veel pogings. Probeer later weer."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Te veel pogings. Gesigstawingsensor is gedeaktiveer."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Probeer weer."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Kleurkorreksie"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Toeganklikheidskortpad het <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Toeganklikheidskortpad het <xliff:g id="SERVICE_NAME">%1$s</xliff:g> afgeskakel"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Gebruik weer toeganklikheidskortpad om die huidige toeganklikheidskenmerk te begin"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Kies \'n kenmerk om te gebruik wanneer jy op die Toeganklikheid-knoppie tik:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Raak en hou die Toeganklikheid-knoppie om kenmerke te verander."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergroting"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 45f962b..217d631 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"ከእርስዎ አገልግሎት አቅራቢ ጋር የWi‑Fi ጥሪን በማስመዝገብ ላይ ችግር፦ <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"የ%s Wi-Fi ጥሪ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> የWi-Fi ጥሪ አደራረግ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"የWLAN ጥሪ"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> የWLAN ጥሪ"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"የWiFi ጥሪ አደራረግ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ጠፍቷል"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ተመርጧል"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"የተንቀሳቃሽ ስልክ ተመራጭ ነው"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"የጣት አሻራ ሃርድዌር አይገኝም።"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"የጣት አሻራ ሊከማች አይችልም። እባክዎ አሁን ያለውን የጣት አሻራ ያስወግዱ።"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"የጣት አሻራ ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"የፊት ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ፊት ሊከማች አይችልም።"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"የፊት ሥርዓተ ክወና ተሰርዟል።"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ፊትን ማረጋገጥ በተጠቃሚ ተሰርዟል።"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"በጣም ብዙ ሙከራዎች። የፊት ማረጋገጫ ተሰናክሏል።"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"እንደገና ይሞክሩ።"</string>
@@ -868,7 +875,7 @@
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"በፊት መክፈት።"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"በፒን መክፈት።"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"የሲም ፒን ክፈት።"</string>
-    <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"የሲም ፒዩኬ ክፈት።"</string>
+    <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"የሲም PUK ክፈት።"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"በይለፍ ቃል መክፈት።"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"የስርዓተ-ጥለት አካባቢ።"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"የማንሸራተቻ አካባቢ።"</string>
@@ -1582,7 +1589,7 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ሲም ካርዱን በመክፈት ላይ…"</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ትክክል ያልሆነ ፒን ኮድ።"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ይተይቡ።"</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"የፒዩኬ ኮድ 8 ቁጥሮች ነው መሆን ያለበት።"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"የPUK ኮድ 8 ቁጥሮች ነው መሆን ያለበት።"</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"ትክክለኛውን የPUK ኮድ እንደገና ያስገቡ። ተደጋጋሚ ሙከራዎች ሲም ካርዱን እስከመጨረሻው ያሰናክሉታል።"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ፒን ኮዶች አይገጣጠሙም"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"በጣም ብዙ የስርዓተ ጥለት ሙከራዎች"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"የቀለም ማስተካከያ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"የተደራሽነት አቋራጭ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን አብርቶታል"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"የተደራሽነት አቋራጭ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን አጥፍቶታል"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"አሁን ያለውን የተደራሽነት ባህሪ ለመጀመር እንደገና የተደራሽነት አቋራጭን ይጠቀሙ"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን ባህሪ ይምረጡ፦"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ባህሪያትን ለመለወጥ የተደራሽነት አዝራሩን ይንኩ እና ይያዙት።"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ማጉላት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index bbdea6a..c11279a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -132,10 +132,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"‏حدثت مشكلة أثناء تسجيل الاتصال عبر Wi‑Fi باستخدام مشغِّل شبكة الجوّال: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"‏%s الاتصال عبر Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏الاتصال عبر شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏مكالمة عبر شبكة WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏مكالمة عبر شبكة WLAN التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"‏شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"‏الاتصال عبر شبكة WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"‏شبكة VoWifi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"إيقاف"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏شبكة Wi-Fi مفضّلة"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"شبكة بيانات الجوال مفضَّلة"</string>
@@ -536,6 +540,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"جهاز بصمة الإصبع غير متاح."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"يتعذر تخزين بصمة الإصبع؛ يرجى إزالة إحدى البصمات المخزنة."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"تم بلوغ مهلة إدخال بصمة الإصبع. أعد المحاولة."</string>
@@ -572,6 +578,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"انتهت مهلة التعرُّف على الوجه. أعِد المحاولة."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"يتعذَّر حفظ الوجه."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"تمّ إلغاء عملية مصادقة الوجه."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ألغَى المستخدم مصادقة الوجه."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"تمّ إجراء محاولات كثيرة. أعِد المحاولة لاحقًا."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"تمّ إجراء محاولات كثيرة. ميزة مصادقة الوجه متوقفة."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"يُرجى إعادة المحاولة."</string>
@@ -1712,6 +1719,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"تصحيح الألوان"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"شغَّل اختصار إمكانية الوصول خدمة <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"أوقف اختصار إمكانية الوصول خدمة <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"استخدِم اختصار إمكانية الوصول لبدء ميزة إمكانية الوصول الحالية."</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"يمكنك اختيار إحدى الميزات لاستخدامها عند النقر على زر إمكانية الوصول:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"لتغيير الميزات، يمكنك لمس زر \"إمكانية الوصول\" مع الاستمرار."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"التكبير"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 48d44b0..5a0a7ec 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"আপোনাৰ বাহকৰ ওচৰত ৱাই-ফাই কলিং সুবিধা পঞ্জীয়ন কৰাত সমস্যাৰ উদ্ভৱ হৈছে: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ৱাই- ফাই কলিং"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ৱাই- ফাই কলিং"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ৱাই- ফাই কলিং | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"অফ হৈ আছে"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ৱাই-ফাইক অগ্ৰাধিকাৰ দিয়া হৈছে"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ম\'বাইলক অগ্ৰাধিকাৰ দিয়া হৈছে"</string>
@@ -308,7 +312,7 @@
     <string name="permgrouprequest_visual" msgid="6907523945030290376">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক আপোনাৰ ফট’ আৰু ভিডিঅ’সমূহ এক্সেছ কৰিবলৈ দিবনে?"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ৱিণ্ড\' সমল বিচাৰি উলিয়াওক"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপুনি যোগাযোগ কৰি থকা ৱিণ্ড\'খনৰ সমল পৰীক্ষা কৰক।"</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পৰ্শৰদ্বাৰা অন্বেষণ কৰাৰ সুবিধা অন কৰক"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পৰ্শৰ দ্বাৰা অন্বেষণ কৰাৰ সুবিধা অন কৰক"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"টেপ কৰা বস্তুসমূহ ডাঙৰকৈ কোৱা হ\'ব আৰু আঙুলিৰ স্পৰ্শেৰে নিৰ্দেশ দি স্ক্ৰীণ অন্বেষণ কৰিব পাৰিব।"</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"আপুনি লিখা পাঠ নিৰীক্ষণ কৰক"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ক্ৰেডিট কাৰ্ডৰ নম্বৰ আৰু পাছৱৰ্ডৰ দৰে ব্যক্তিগত ডেটা অন্তৰ্ভুক্ত হ\'ব পাৰে।"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ নাই।"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ফিংগাৰপ্ৰিণ্ট সঞ্চয় কৰিব পৰা নগ\'ল। পূর্বে সঞ্চিত ফিংগাৰপ্ৰিণ্ট এটা আঁতৰাওক।"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ফিংগাৰপ্ৰিণ্ট গ্ৰহণৰ সময়সীমা উকলি গৈছে। আকৌ চেষ্টা কৰক।"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"মুখমণ্ডল গ্ৰহণৰ সময়সীমা উকলি গৈছে। আকৌ চেষ্টা কৰক।"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"মুখমণ্ডল সঞ্চয় কৰিব নোৱাৰি।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"মুখমণ্ডলৰ প্ৰক্ৰিয়া বাতিল কৰা হ’ল।"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ব্যৱহাৰকাৰীয়ে মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰিছে।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"অত্যধিক ভুল প্ৰয়াস। কিছুসময়ৰ পাছত আকৌ চেষ্টা কৰক।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"অত্যধিক প্ৰয়াস। মুখমণ্ডলৰ জৰিয়তে সত্যাপন অক্ষম কৰা হ’ল।"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"আকৌ চেষ্টা কৰক।"</string>
@@ -1404,7 +1411,7 @@
     <string name="forward_intent_to_work" msgid="621480743856004612">"আপুনি আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলৰ ভিতৰত এই এপটো ব্যৱহাৰ কৰি আছে"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"ইনপুট পদ্ধতি"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"ছিংক"</string>
-    <string name="accessibility_binding_label" msgid="4148120742096474641">"সাধ্য় সুবিধাসমূহ"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"সাধ্য সুবিধাসমূহ"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"ৱালপেপাৰ"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"ৱালপেপাৰ সলনি কৰক"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"জাননী নিৰীক্ষক"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ৰং শুধৰণী"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাটটোৱে <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ক অন কৰিছে"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাটটোৱে <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ক অফ কৰিছে"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"বর্তমানৰ সাধ্য সুবিধাসমূহৰ আৰম্ভ কৰিবলৈ সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট পুনৰ ব্যৱহাৰ কৰক"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"আপুনি দিব্যাংগসকলৰ সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলগীয়া কোনো সুবিধা বাছক:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"সুবিধাসমূহ সলনি কৰিবলৈ দিব্যাংগসকলৰ সুবিধাৰ বুটামটো স্পৰ্শ কৰি থাকক।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বিবৰ্ধন"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 44bcd56..af65bbb 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Operatorla Wi‑Fi zənglərini qeydə alarkən xəta baş verdi: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Zəngi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Zəngi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Zəngi"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Zəngi"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi Zəngi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Deaktiv"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi tərcih edilir"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil tərcih"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Tanınmır"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Barmaq izi doğrulandı"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Üz doğrulandı"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Üz təsdiq edildi, təsdiq düyməsinə basın"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Barmaq izi üçün avadanlıq yoxdur."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Barmaq izi saxlana bilməz. Lütfən, mövcud barmaq izini silin."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Barmaq izinin vaxtı başa çatdı. Yenidən cəhd edin."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Üz proqramı taymerinin vaxtı bitdi. Yenidən cəhd edin."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Üz bərpa edilmədi."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Üz əməliyyatı ləğv edildi."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Üz dorğulaması istifadəçi tərəfindən ləğv edildi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Həddindən çox cəhd. Sonraya saxlayın."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Həddindən çox cəhd. Üz identifikasiyası deaktiv edildi."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Yenidən cəhd edin."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Rəng korreksiyası"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Əlçatımlıq Qısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etdi"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Əlçatımlıq Qısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini deaktiv etdi"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Cari əlçatımlılıq funksiyasını yenidən başlatmaq üçün Əlçatımlılıq Qısayolundan istifadə edin"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Əlçatımlılıq düyməsinə kliklədikdə istifadə etmək üçün funksiya seçin:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funksiyaları dəyişmək üçün Əlçatımlılıq düyməsinə basıb saxlayın."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Böyütmə"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 260f63e..805082a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -129,10 +129,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Problem u vezi sa registrovanjem pozivanja preko Wi‑Fi-ja kod mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Wi-Fi pozivanje preko operatera %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko Wi-Fi-ja"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN poziv"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Pozivanje preko Wi-Fi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Želim mobilne podatke"</string>
@@ -527,6 +531,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nije prepoznato"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Otisak prsta je potvrđen"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Lice je potvrđeno"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Lice je potvrđeno. Pritisnite Potvrdi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardver za otiske prstiju nije dostupan."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Nije moguće sačuvati otisak prsta. Uklonite neki od postojećih otisaka prstiju."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Probajte ponovo."</string>
@@ -563,6 +569,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Isteklo je vreme za proveru lica. Probajte ponovo."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Nije moguće sačuvati lice."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Obrada lica je otkazana."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Korisnik je otkazao potvrdu lica."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Probajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Više pokušaja. Potvrda identiteta je onemogućena."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Probajte ponovo."</string>
@@ -1640,6 +1647,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korekcija boja"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Upotrebite ponovo prečicu za pristupačnost da biste pokrenuli aktuelnu funkciju pristupačnosti"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pritisnite i zadržite dugme za pristupačnost da biste menjali funkcije."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 3d46662..7692220 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Памылка падключэння Wi‑Fi-тэлефаніі ў вашага аператара: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Wi-Fi-тэлефанія %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-тэлефанія ад <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Выклік праз WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Выклік праз WLAN ад <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ад <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-тэлефанія | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWi-Fi ад <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Выкл."</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Прыярытэт Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Прыярытэт мабільнай сеткі"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Апаратныя сродкі адбіткаў пальцаў недаступныя."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Адбіткі пальцаў нельга захаваць. Выдаліце існы адбітак."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час чакання адбіткаў пальцаў выйшаў. Паспрабуйце яшчэ раз."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Час чакання твару выйшаў. Паўтарыце спробу."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Не ўдалося захаваць твар."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Распазнаванне твару скасавана."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Распазнаванне твару скасавана карыстальнікам."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Занадта шмат спроб. Паўтарыце спробу пазней."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Занадта шмат спроб. Аўтэнтыфікацыя твару адключана"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Паўтарыце спробу."</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Карэкцыя колеру"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў уключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў адключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Каб запусціць функцыю спецыяльных магчымасцей, паўторна скарыстайце ярлык спецыяльных магчымасцей"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберыце функцыю для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Каб змяняць функцыі, краніце і ўтрымлівайце кнопку \"Спецыяльныя магчымасці\"."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Павелічэнне"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e9ecba6..33c4898 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"При регистрирането на функцията за обаждания през Wi-Fi с оператора ви възникна грешка: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s – обаждания през Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Обаждания през Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Обаждане през WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Обаждане през WLAN от <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Обаждания през Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Изключено"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Предпочита се Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Предпочитат се мобилни данни"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Хардуерът за отпечатъци не е налице."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Отпечатъкът не може да бъде съхранен. Моля, премахнете съществуващ."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Времето за изчакване за отпечатък изтече. Опитайте отново."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Времето за изчакване изтече. Опитайте отново."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Лицето не може да бъде съхранено."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Операцията с лице е анулирана."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Удостоверяв. на лицето е анулирано от потребителя."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Твърде много опити. Опитайте отново по-късно."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Твърде много опити. Удост. с лице е деактивирано."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Опитайте отново."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Коригиране на цветовете"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Прекият път за достъпност включи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Прекият път за достъпност изключи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Използвайте отново прекия път към функцията за достъпност, за да стартирате текущата"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изберете функция, която да използвате, когато докоснете бутона за достъпност:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"За да промените функции, докоснете и задръжте бутона за достъпност."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ниво на мащаба"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 4ece21b..f0787b4 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"পরিষেবা প্রদানকারীতে ওয়াই-ফাই কলিং রেজিস্টার করতে সমস্যা হয়েছে: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ওয়াই-ফাই কলিং"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই কলিং"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ওয়াই-ফাই কলিং | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"বন্ধ আছে"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"পছন্দের ওয়াই-ফাই"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"পছন্দের মোবাইল"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার অনুপলব্ধ৷"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"আঙ্গুলের ছাপ সংরক্ষণ করা যাবে না৷ অনুগ্রহ করে একটি বিদ্যমান আঙ্গুলের ছাপ সরান৷"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"আঙ্গুলের ছাপ নেওয়ার সময়সীমা শেষ হযেছে৷ আবার চেষ্টা করুন৷"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ফেসের ছাপ নেওয়ার সময়সীমা শেষ৷ আবার চেষ্টা করুন৷"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ফেস স্টোর করা যাবে না।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ফেস অপারেশন বাতিল করা হয়েছে৷"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ফেস যাচাইকরণ ব্যবহারকারীর দ্বারা বাতিল করা হয়েছে।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"অনেকবার চেষ্টা করা হয়েছে। পরে আবার চেষ্টা করুন।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"অনেকবার চেষ্টা করা হয়েছে৷ ফেস যাচাইকরণ বন্ধ আছে।"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"আবার চেষ্টা করুন।"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"রঙ সংশোধন"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে চালু করেছে"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে বন্ধ করেছে"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"বর্তমান অ্যাক্সেসিবিলিটি বৈশিষ্ট্য শুরু করার জন্য অ্যাক্সেসিবিলিটি শর্টকাটটি আবার ব্যবহার করুন"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"অ্যাক্সেসযোগ্যতা বোতামের সাহায্যে যে বৈশিষ্ট্যটি নিয়ন্ত্রণ করতে চান, সেটি বেছে নিন:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"বৈশিষ্ট্যগুলি পরিবর্তন করতে অ্যাক্সেসযোগ্যতা বোতামটি ট্যাপ করে ধরে রাখুন।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বড় করে দেখা"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 918ecf9..e895ce0 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -129,10 +129,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Došlo je do problema prilikom registracije pozivanja putem WiFi mreže kod vašeg operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Pozivanje putem WiFi-ja preko operatera %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Pozivanje putem WiFi-ja"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN poziv"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Pozivanje putem WiFi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferira se WiFi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferira se mobilna mreža"</string>
@@ -527,6 +531,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nije prepoznato"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Otisak prsta je potvrđen"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Lice je provjereno"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Lice je provjereno, pritisnite dugme za potvrdu"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardver za otisak prsta nije dostupan."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Otisak prsta se ne može pohraniti. Uklonite postojeći otisak prsta."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vrijeme za prepoznavanje otiska prsta je isteklo. Pokušajte ponovo."</string>
@@ -563,6 +569,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Vrijeme za prepoznavanje lica je isteklo. Pokušajte ponovo."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Nije moguće pohraniti lice."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Prepoznavanje lica je otkazano."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Korisnik je otkazao provjeru lica."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Previše pokušaja. Autentifikacija lica onemogućena."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Pokušajte ponovo."</string>
@@ -1512,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>
@@ -1642,6 +1649,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Ispravka boja"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Ponovo koristite Prečicu za pristupačnost da započnete trenutnu funkciju pristupačnosti"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Odaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da promijenite funkcije, dodirnite i držite dugme Pristupačnost."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f6c46ba..b1d4994 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Hi ha hagut un problema en registrar les trucades per Wi-Fi amb el teu operador de telefonia mòbil: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Trucades per Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Trucades per Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Trucada per WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Trucada per WLAN (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Trucades per Wi‑Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivat"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferència per la Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferència per dades mòbils"</string>
@@ -295,7 +299,7 @@
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"llegir i editar el registre de trucades del telèfon"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Vols permetre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; accedeixi als registres de trucades del telèfon?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Telèfon"</string>
-    <string name="permgroupdesc_phone" msgid="6234224354060641055">"fer i gestionar trucades telefòniques"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"fer i gestionar trucades"</string>
     <string name="permgrouprequest_phone" msgid="9166979577750581037">"Vols permetre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; faci trucades i les gestioni?"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensors corporals"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accedir a les dades del sensor sobre els signes vitals"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"No s\'ha reconegut"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"L\'empremta digital s\'ha autenticat"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Cara autenticada"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Cara autenticada; prem el botó per confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"El maquinari per a empremtes digitals no està disponible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"L\'empremta digital no es pot desar. Suprimeix-ne una."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"S\'ha esgotat el temps d\'espera. Torna-ho a provar."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"La cara no es pot desar."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"S\'ha cancel·lat el reconeixement facial."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticació facial cancel·lada per l\'usuari."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Massa intents. Torna-ho a provar més tard."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Massa intents. Autenticació facial desactivada."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Torna-ho a provar."</string>
@@ -804,8 +811,8 @@
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Falta la targeta SIM o no es pot llegir. Insereix-ne una."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Targeta SIM no utilitzable."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"La targeta SIM està desactivada permanentment.\n Contacta amb el teu proveïdor de serveis sense fil per obtenir-ne una altra."</string>
-    <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Ruta anterior"</string>
-    <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Ruta següent"</string>
+    <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Pista anterior"</string>
+    <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Pista següent"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Posa en pausa"</string>
     <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"Reprodueix"</string>
     <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Atura"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correcció del color"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"La drecera d\'accessibilitat ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"La drecera d\'accessibilitat ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Torna a utilitzar la drecera d\'accessibilitat per iniciar la funció d\'accessibilitat actual"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Tria la funció que s\'utilitzarà quan toquis el botó Accessibilitat:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Per canviar les funcions, toca i mantén premut el botó Accessibilitat."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliació"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e882f42..a537d6d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Při registraci volání přes Wi-Fi u operátora <xliff:g id="CODE">%1$s</xliff:g> došlo k chybě"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Volání přes Wi-Fi: %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>: volání přes Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Volání přes WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>: volání přes WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Volání přes Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>: VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuto"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferována síť W-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferována mobilní data"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nerozpoznáno"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Otisk byl ověřen"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Obličej byl ověřen"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Obličej byl ověřen, stiskněte tlačítko pro potvrzení"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Není k dispozici hardware ke snímání otisků prstů."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Otisk prstu nelze uložit. Odstraňte existující otisk prstu."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Časový limit sejmutí otisku prstu vypršel. Zkuste to znovu."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Limit ověření obličeje vypršel. Zkuste to znovu."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Obličej nelze uložit."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operace snímání obličeje byla zrušena."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Ověření obličeje bylo zrušeno uživatelem."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Příliš mnoho pokusů. Zkuste to později."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Příliš mnoho pokusů. Ověření obličeje je zakázáno."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Zkuste to znovu."</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Oprava barev"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Zkratka přístupnosti zapnula službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Zkratka přístupnosti vypnula službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Znovu použijte zkratku přístupnosti, čímž spustíte aktuální funkci pro usnadnění přístupu"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Určete, jakou funkci aktivujete klepnutím na tlačítko Přístupnost:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Chcete-li vybrat jinou funkci, podržte tlačítko Přístupnost."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zvětšení"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9a793a8..28c08b1 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Der opstod et problem under registrering af Wi-Fi-opkald hos dit mobilselskab: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi-opkald"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-opkald via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-opkald"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-opkald via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-opkald | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi via <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Fra"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WiFi-netværk er foretrukket"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobildata foretrækkes"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Ikke genkendt"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingeraftrykket blev godkendt"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Ansigtet er godkendt"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Ansigtet er godkendt. Tryk på Bekræft."</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardwaren til fingeraftryk er ikke tilgængelig."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingeraftrykket kan ikke gemmes. Fjern et eksisterende fingeraftryk."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Registrering af fingeraftryk fik timeout. Prøv igen."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Ansigtsgenkendelse fik timeout. Prøv igen."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Ansigtet kan ikke gemmes."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansigtshandlingen blev annulleret."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Ansigtsgodkendelsen blev annulleret af brugeren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Du har prøvet for mange gange. Prøv igen senere."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"For mange forsøg – Ansigtsgenkendelse deaktiveret."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Prøv igen."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korriger farve"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Genvejen til hjælpefunktioner aktiverede <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Genvejen til hjælpefunktioner deaktiverede <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Brug Genvej til hjælpefunktioner for at starte den aktuelle hjælpefunktion"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen Hjælpefunktioner:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Tryk på knappen Hjælpefunktioner, og hold fingeren nede for at skifte funktioner."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Forstørrelse"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8eb0eb8..4a2efbd 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Probleme beim Registrieren der WLAN-Telefonie bei deinem Mobilfunkanbieter: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s WLAN-Telefonie"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> WLAN-Telefonie"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-Anruf"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-Anruf"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WLAN-Telefonie | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWLAN"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Aus"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WLAN bevorzugt"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobilverbindung bevorzugt"</string>
@@ -150,7 +154,7 @@
     <string name="httpErrorAuth" msgid="1435065629438044534">"Bei der Authentifizierung ist ein Fehler aufgetreten."</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Authentifizierung via Proxyserver ist fehlgeschlagen."</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"Verbindung zum Server konnte nicht hergestellt werden."</string>
-    <string name="httpErrorIO" msgid="2340558197489302188">"Kommunikation mit dem Server konnte nicht hergestellt werden. Bitte versuche es später erneut."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Kommunikation mit dem Server konnte nicht hergestellt werden. Bitte versuche es später noch einmal."</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"Zeitüberschreitung bei Serververbindung."</string>
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Die Seite enthält zu viele Server-Redirects."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Das Protokoll wird nicht unterstützt."</string>
@@ -158,7 +162,7 @@
     <string name="httpErrorBadUrl" msgid="3636929722728881972">"Die Seite kann nicht geöffnet werden, weil die URL ungültig ist."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"Auf die Datei konnte nicht zugegriffen werden."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Die angeforderte Datei wurde nicht gefunden."</string>
-    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Es werden zurzeit zu viele Anfragen verarbeitet. Versuche es später erneut."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Es werden zurzeit zu viele Anfragen verarbeitet. Bitte versuche es später noch einmal."</string>
     <string name="notification_title" msgid="8967710025036163822">"Fehler bei Anmeldung für <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchronisierung"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="7036196943673524858">"Synchronisierung nicht möglich"</string>
@@ -515,23 +519,25 @@
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"Standorte aus meiner Mediensammlung abrufen"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"Ermöglicht der App, Standorte aus deiner Mediensammlung abzurufen."</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Biometrische Hardware nicht verfügbar"</string>
-    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Fingerabdruck teilweise erkannt. Versuche es erneut."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Fingerabdruck konnte nicht verarbeitet werden. Versuche es erneut."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingerabdrucksensor ist verschmutzt. Reinige ihn und versuche es erneut."</string>
-    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger zu schnell bewegt. Versuche es erneut."</string>
-    <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Finger zu langsam bewegt. Versuche es erneut."</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Fingerabdruck teilweise erkannt. Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingerabdrucksensor ist verschmutzt. Reinige ihn und versuche es noch einmal."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger zu schnell bewegt. Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Finger zu langsam bewegt. Bitte versuche es noch einmal."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nicht erkannt"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingerabdruck wurde authentifiziert"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Gesicht authentifiziert"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Gesicht authentifiziert, bitte bestätigen"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerabdruckhardware nicht verfügbar"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerabdruck kann nicht gespeichert werden. Entferne einen vorhandenen Fingerabdruck."</string>
-    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Versuche es erneut."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Bitte versuche es noch einmal."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerabdruckvorgang abgebrochen"</string>
     <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Vorgang der Fingerabdruckauthentifizierung vom Nutzer abgebrochen."</string>
-    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Versuche es später erneut."</string>
+    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Bitte versuche es später noch einmal."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Zu viele Versuche. Der Fingerabdrucksensor wurde deaktiviert."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuche es erneut."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuche es noch einmal."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Keine Fingerabdrücke erfasst."</string>
     <string name="fingerprint_error_hw_not_present" msgid="5729436878065119329">"Dieses Gerät hat keinen Fingerabdrucksensor"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Zeitüberschreitung für Gesicht. Versuch es erneut."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Gesicht kann nicht gespeichert werden."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Gesichtserkennung abgebrochen."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Gesichtsauthentifizierung vom Nutzer abgebrochen."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Zu viele Versuche. Versuch es später noch einmal."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Zu viele Versuche. Gesichtserkennung deaktiviert."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Versuch es noch einmal."</string>
@@ -1085,7 +1092,7 @@
     <string name="view_flight" msgid="7691640491425680214">"Verfolgen"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"Ausgewählten Flug verfolgen"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
-    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren eventuell nicht."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der Speicherplatz reicht nicht für das System aus. Stelle sicher, dass 250 MB freier Speicherplatz vorhanden sind, und starte das Gerät dann neu."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird ausgeführt"</string>
     <string name="app_running_notification_text" msgid="1197581823314971177">"Für weitere Informationen oder zum Beenden der App tippen."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Farbkorrektur"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> wurde durch die Bedienungshilfenverknüpfung aktiviert"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> wurde durch die Bedienungshilfenverknüpfung deaktiviert"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Verwende noch einmal die Verknüpfung für Bedienungshilfen, um die aktuelle Bedienungshilfe zu starten."</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Wähle eine Funktion aus, die verwendet wird, wenn du auf die Schaltfläche für die Bedienungshilfen tippst:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Um die Funktionen zu ändern, halte die Schaltfläche für die Bedienungshilfen gedrückt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergrößerung"</string>
@@ -1723,7 +1731,7 @@
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Neue PIN"</string>
     <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Neue PIN bestätigen"</string>
     <string name="restr_pin_create_pin" msgid="8017600000263450337">"PIN für das Ändern von Einschränkungen erstellen"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Die PINs stimmen nicht überein. Bitte versuche es erneut."</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Die PINs stimmen nicht überein. Bitte versuche es noch einmal."</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Die PIN ist zu kurz. Sie muss mindestens 4 Ziffern umfassen."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
       <item quantity="other">In <xliff:g id="COUNT">%d</xliff:g> Sek. wiederholen</item>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 3a50f9e..04b9749 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Παρουσιάστηκε πρόβλημα με την εγγραφή της κλήσης Wi‑Fi με την εταιρεία κινητής τηλεφωνίας: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Κλήση Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Κλήση Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Κλήση μέσω WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Κλήση μέσω WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Κλήση Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ανενεργό"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Προτίμηση Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Προτίμηση δικτύου κινητής τηλεφωνίας"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Ο εξοπλισμός μοναδικού χαρακτηριστικού δεν είναι διαθέσιμος."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Δεν είναι δυνατή η αποθήκευση μοναδικού χαρακτηριστικού. Καταργήστε το υπάρχον μοναδικό χαρακτηριστικό."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Λήξη χρονικού ορίου μοναδικού χαρακτηριστικού. Δοκιμάστε ξανά."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Λήξη χρονικού ορίου προσώπου. Δοκιμάστε ξανά."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Δεν είναι δυνατή η αποθήκευση του προσώπου."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Η ενέργεια προσώπου ακυρώθηκε."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Ο έλεγχος ταυτότητας προσώπου ακυρώθηκε από τον χρήστη."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Πάρα πολλές προσπάθειες. Δοκιμάστε ξανά αργότερα."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Πολλές προσπάθειες. Αποτυχία ελέγ. ταυτ. προσώπου."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Δοκιμάστε ξανά."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Διόρθωση χρωμάτων"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Η συντόμευση προσβασιμότητας ενεργοποίησε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Η συντόμευση προσβασιμότητας απενεργοποίησε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Χρησιμοποιήστε τη Συντόμευση προσβασιμότητας ξανά, για να ξεκινήσετε την τρέχουσα λειτουργία προσβασιμότητας"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού \"Προσβασιμότητα\"."</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Για να αλλάξετε λειτουργίες, αγγίξτε παρατεταμένα το κουμπί \"Προσβασιμότητα\"."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Μεγιστοποίηση"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 04b20ba..8592355 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Issue registering Wi‑Fi calling with your operator: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Calling"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Not recognised"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingerprint authenticated"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Face authenticated"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerprint can\'t be stored. Please remove an existing fingerprint."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Colour Correction"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Use Accessibility Shortcut again to start the current accessibility feature"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index c1ca0c4..1e075f8 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Issue registering Wi‑Fi calling with your operator: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Calling"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Not recognised"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingerprint authenticated"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Face authenticated"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerprint can\'t be stored. Please remove an existing fingerprint."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Colour Correction"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Use Accessibility Shortcut again to start the current accessibility feature"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 04b20ba..8592355 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Issue registering Wi‑Fi calling with your operator: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Calling"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Not recognised"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingerprint authenticated"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Face authenticated"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerprint can\'t be stored. Please remove an existing fingerprint."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Colour Correction"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Use Accessibility Shortcut again to start the current accessibility feature"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 04b20ba..8592355 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Issue registering Wi‑Fi calling with your operator: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Calling"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Not recognised"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingerprint authenticated"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Face authenticated"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerprint can\'t be stored. Please remove an existing fingerprint."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Colour Correction"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Use Accessibility Shortcut again to start the current accessibility feature"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 4add775..9138098 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎Issue registering Wi‑Fi calling with your carrier: ‎‏‎‎‏‏‎<xliff:g id="CODE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎%s‎‏‎‎‏‎"</item>
-    <item msgid="4397097370387921767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎%s Wi-Fi Calling‎‏‎‎‏‎"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ Wi-Fi Calling‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎WLAN Call‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ WLAN Call‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ Wi-Fi‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎WiFi Calling | ‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ VoWifi‎‏‎‎‏‎"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎Off‎‏‎‎‏‎"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎Wi-Fi preferred‎‏‎‎‏‎"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Mobile preferred‎‏‎‎‏‎"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‎Not recognized‎‏‎‎‏‎"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎Fingerprint authenticated‎‏‎‎‏‎"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎Face authenticated‎‏‎‎‏‎"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎Face authenticated, please press confirm‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎Fingerprint hardware not available.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‎Fingerprint can\'t be stored. Please remove an existing fingerprint.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎Fingerprint time out reached. Try again.‎‏‎‎‏‎"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎Face time out reached. Try again.‎‏‎‎‏‎"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎Face can’t be stored.‎‏‎‎‏‎"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎Face operation canceled.‎‏‎‎‏‎"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎Face authentication canceled by user.‎‏‎‎‏‎"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎Too many attempts. Try again later.‎‏‎‎‏‎"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎Too many attempts. Facial authentication disabled.‎‏‎‎‏‎"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎Try again.‎‏‎‎‏‎"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎Color Correction‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎Accessibility Shortcut turned ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ on‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎Accessibility Shortcut turned ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ off‎‏‎‎‏‎"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎Use Accessibility Shortcut again to start the current accessibility feature‎‏‎‎‏‎"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎Choose a feature to use when you tap the Accessibility button:‎‏‎‎‏‎"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎To change features, touch &amp; hold the Accessibility button.‎‏‎‎‏‎"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎Magnification‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f317a4e..6176b7b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Error al registrar la Llamada con Wi‑Fi con tu operador: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Llamada por Wi-Fi de %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Llamada por Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Llamada por WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Llamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Llamada por Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivada"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Red Wi-Fi preferida"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Red móvil preferida"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"No se reconoció"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Se autenticó la huella digital"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Se autenticó el rostro"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Se autenticó el rostro; presiona Confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"El hardware para detectar huellas digitales no está disponible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"No se puede almacenar la huella digital. Elimina una de las existentes."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Finalizó el tiempo de espera para la huella digital. Vuelve a intentarlo."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Se agotó el tiempo. Vuelve a intentarlo."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"No se puede almacenar el rostro."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Se canceló el reconocimiento facial."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"El usuario canceló la autenticación de rostro."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiados intentos. Autent. facial inhabilitada."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Vuelve a intentarlo."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Corrección de color"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"El acceso directo de accesibilidad activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo de accesibilidad desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Vuelve a usar el acceso directo de accesibilidad para iniciar la función de accesibilidad actual"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Elige una función para usar cuando presionas el botón Accesibilidad:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar funciones, mantén presionado el botón Accesibilidad."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliación"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index c42f53c..dd766f7 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"No se ha podido registrar la llamada por Wi‑Fi con tu operador: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Llamadas Wi-Fi de %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Llamada por Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Llamada por WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Llamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Llamada por Wi‑Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWiFi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Dar preferencia a Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferir datos móviles"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"No se reconoce"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Se ha autenticado la huella digital"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Cara autenticada"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Se ha autenticado la cara, pulsa para confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"El hardware de huella digital no está disponible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"No se puede almacenar la huella digital. Elimina una ya creada."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Se ha alcanzado el tiempo de espera de la huella digital. Vuelve a intentarlo."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Has sobrepasado el tiempo. Inténtalo de nuevo."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"No se pueden registrar más caras."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Se ha cancelado el reconocimiento facial."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"El usuario ha cancelado la autenticación de la cara."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiados intentos. Autent. facial inhabilitada."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Inténtalo de nuevo."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Corrección de color"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"El acceso directo a accesibilidad ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo a accesibilidad ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Usa de nuevo la combinación de teclas de accesibilidad para iniciar la función de accesibilidad actual"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Selecciona la función que se utilizará cuando toques el botón Accesibilidad:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar las funciones, mantén pulsado el botón Accesibilidad."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliar"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index cc052c4..650fcb6 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Probleem WiFi-kõnede registreerimisel teie operaatoriga: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s WiFi kaudu helistamine"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>: WiFi-kõned"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-kõne"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>: WLAN-kõne"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: WiFi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi-kõne | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>: VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Väljas"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WiFi eelistusega"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Eelistatud on mobiilne andmeside"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Ei tuvastatud"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Sõrmejälg autenditi"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Nägu on autenditud"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Nägu on autenditud, vajutage käsku Kinnita"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Sõrmejälje riistvara pole saadaval."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Sõrmejälge ei saa salvestada. Eemaldage olemasolev sõrmejälg."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Sõrmejälje riistvara taimeri ajalõpp. Proovige uuesti."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Näotuvastuse taimeri ajalõpp. Proovige uuesti."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Nägu ei saa salvestada."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Näotuvastuse toiming tühistati."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Kasutaja tühistas näo autentimise."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Liiga palju katseid. Proovige hiljem uuesti."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Liiga palju katseid. Näotuvastus on keelatud."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Proovige uuesti."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Värviparandus"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisse"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> välja"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Praeguse juurdepääsufunktsiooni käivitamiseks kasutage juurdpääsetavuse otseteed uuesti"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Valige, millist funktsiooni kasutada, kui vajutate nuppu Juurdepääsetavus:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funktsioonide muutmiseks puudutage pikalt nuppu Juurdepääsetavus."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Suurendus"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 275e171..6a6fdbf 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Arazo bat izan da Wi‑Fi bidezko deiak zure operadorearekin erregistratzean: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi bidezko deiak"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi bidezko deiak"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN bidezko deia"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN bidezko deia"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi bidezko deiak | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desaktibatuta"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi sarea hobesten da"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Datu-konexioa hobesten da"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Ez da ezagutu"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Autentifikatu da hatz-marka"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Autentifikatu da aurpegia"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Autentifikatu da aurpegia; sakatu Berretsi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hatz-markaren hardwarea ez dago erabilgarri."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Ezin da gorde hatz-marka digitala. Kendu lehendik gordeta duzunetako bat."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Hatz-marka digitalak prozesatzeko denbora-muga gainditu da. Saiatu berriro."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Gainditu da aurpegiak prozesatzeko denbora-muga. Saiatu berriro."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Ezin da gorde aurpegia."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Utzi da aurpegiaren bidezko eragiketa."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Erabiltzaileak utzi du aurpegi-autentifikazioa."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Saiakera gehiegi egin dituzu. Desgaitu egin da autentifikazioa."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Saiatu berriro."</string>
@@ -1129,7 +1136,7 @@
     <string name="aerr_application_repeated" msgid="3146328699537439573">"Behin eta berriz gelditzen ari da <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"Behin eta berriz gelditzen ari da <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Ireki aplikazioa berriro"</string>
-    <string name="aerr_report" msgid="5371800241488400617">"Bidali iritzia"</string>
+    <string name="aerr_report" msgid="5371800241488400617">"Bidali oharrak"</string>
     <string name="aerr_close" msgid="2991640326563991340">"Itxi"</string>
     <string name="aerr_mute" msgid="1974781923723235953">"Ezkutatu gailua berrabiarazi arte"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"Itxaron"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Koloreen zuzenketa"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Erabilerraztasun-lasterbideak <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu du"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Erabilerraztasun-lasterbideak <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu du"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Uneko erabilerraztasun-eginbidea abiarazteko, erabili erabilerraztasun-lasterbidea berriro"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Eginbideak aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Lupa"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5055e8b..2310f9e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"‏مشکل هنگام ثبت تماس ازطریق Wi‑Fi با شرکت مخابراتی: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"‏تماس ‪%s Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏تماس ازطریق Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏تماس ازطریق WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏تماس ازطریق WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"‏درحال تماس ازطریق WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"خاموش"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏Wi-Fi ترجیحی"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"داده شبکه تلفن همراه ارجح است"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"سخت‌افزار اثرانگشت در دسترس نیست."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ذخیره اثر انگشت ممکن نیست. لطفاً یک اثر انگشت موجود را حذف کنید."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"مهلت زمانی ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"مهلت زمانی شناسایی چهره تمام شد. دوباره امتحان کنید"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"نمی‌توان چهره را ذخیره کرد."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"عملیات شناسایی چهره لغو شد."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"احراز هویت چهره توسط کاربر لغو شد."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"تعداد زیادی تلاش ناموفق. بعداً دوباره امتحان کنید."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"چندین تلاش ناموفق. احراز هویت با چهره غیرفعال شد."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"دوباره امتحان کنید."</string>
@@ -890,7 +897,7 @@
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"ماندن در این صفحه"</string>
     <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nمطمئنید می‌خواهید این صفحه را ترک کنید؟"</string>
     <string name="save_password_label" msgid="6860261758665825069">"تأیید"</string>
-    <string name="double_tap_toast" msgid="4595046515400268881">"نکته: برای بزرگ‌نمایی و کوچک‌نمایی، دو بار ضربه بزنید."</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"نکته: برای نزدیک‌نمایی و دورنمایی، دو بار ضربه بزنید."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"تکمیل خودکار"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"راه‌اندازی تکمیل خودکار"</string>
     <string name="autofill_window_title" msgid="4107745526909284887">"تکمیل خودکار با <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"تصحیح رنگ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"«میان‌بر دسترس‌پذیری» <xliff:g id="SERVICE_NAME">%1$s</xliff:g> را روشن کرد"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"«میان‌بر دسترس‌پذیری» <xliff:g id="SERVICE_NAME">%1$s</xliff:g> را خاموش کرد"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"برای راه‌اندازی ویژگی دسترس‌پذیری کنونی، دوباره از «میان‌بر دسترس‌پذیری» استفاده کنید"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"قابلیتی را انتخاب کنید که هنگام ضربه زدن روی دکمه «دسترس‌پذیری» استفاده می‌شود:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"برای تغییر دادن قابلیت‌ها، دکمه «دسترس‌پذیری» را لمس کنید و نگه‌دارید."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"درشت‌نمایی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index d54cb72..4f2531c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Virhe otettaessa Wi-Fi-puheluita käyttöön operaattorille <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Wi-Fi-puhelut: %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-puhelut (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-puhelu"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-puhelu (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-puhelut | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ei käytössä"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ensisijainen"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobiiliverkko ensisijainen"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Ei tunnistettu"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Sormenjälki tunnistettu"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Kasvot tunnistettu"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Kasvot tunnistettu, valitse Vahvista"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Sormenjälkilaitteisto ei ole käytettävissä."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Sormenjälkeä ei voida tallentaa. Poista aiemmin lisätty sormenjälki."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Sormenjälkitunnistimen toiminta aikakatkaistiin. Yritä uudelleen."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Kasvotoiminto aikakatkaistiin. Yritä uudelleen."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Kasvoja ei voi tallentaa."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Kasvotoiminto peruutettu"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Käyttäjä peruutti kasvojentunnistuksen."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Liikaa yrityksiä. Kasvojentodennus ei käytössä."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Yritä uudelleen."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Värinkorjaus"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> otettiin käyttöön esteettömyystilan pikanäppäimellä."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> poistettiin käytöstä esteettömyystilan pikanäppäimellä."</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Valitse esteettömyystilan oikopolku uudelleen käynnistääksesi esteettömyysominaisuuden"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Valitse toiminto, jonka Esteettömyys-painike aktivoi:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Jos haluat muokata ominaisuuksia, kosketa Esteettömyys-painiketta pitkään."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Suurennus"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 0c0cdea..39889ec 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Une erreur s\'est produite lors de l\'enregistrement des appels Wi-Fi avec votre fournisseur de services : <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Appels Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Appel WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Appel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Appels Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"Voix par Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Désactivé"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Réseau Wi-Fi de préférence"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Connexion cellulaire de préférence"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Données biométriques non reconnues"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Empreinte digitale authentifiée"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Visage authentifié"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Matériel d\'empreinte numérique indisponible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"L\'empreinte digitale ne peut pas être enregistrée. Veuillez supprimer une empreinte existante."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte est écoulé. Veuillez essayer de nouveau."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Temps de reconn. visage écoulé. Veuillez réessayer."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Impossible de stocker le visage."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Opération de reconnaissance du visage annulée."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Authentification du visage annulée par l\'utilisateur"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Trop de tentatives. Veuillez réessayer plus tard."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Trop de tentatives. Capt. reconn. visage désactivé."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Réessayez."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correction des couleurs"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Le raccourci d\'accessibilité a activé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Utilisez à nouveau le raccourci d\'accessibilité pour démarrer la fonctionnalité d\'accessibilité actuelle"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choisissez une fonctionnalité à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pour changer des fonctionnalités, maintenez le doigt sur le bouton d\'accessibilité."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zoom"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e153082..9759415 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Problème lors de l\'enregistrement des appels Wi‑Fi avec votre opérateur : <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Appels Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Appel WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Appel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Appels Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWiFi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Désactivé"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi de préférence"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Priorité au mobile"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Non reconnu"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Empreinte digitale authentifiée"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Visage authentifié"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Visage authentifié, veuillez appuyer sur \"Confirmer\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Matériel d\'empreinte numérique indisponible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Impossible d\'enregistrer l\'empreinte numérique. Veuillez supprimer une empreinte."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Délai de détection de l\'empreinte numérique expiré. Veuillez réessayer."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Délai de détection du visage expiré. Réessayez."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Impossible de stocker les informations du visage."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Opération de reconnaissance faciale annulée."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Authentification faciale annulée par l\'utilisateur."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Trop de tentatives. Réessayez plus tard."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Trop d\'essais. Authentification faciale désactivée."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Réessayez."</string>
@@ -1300,14 +1307,14 @@
     <string name="perm_costs_money" msgid="4902470324142151116">"Cela peut engendrer des frais"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
     <string name="usb_charging_notification_title" msgid="1595122345358177163">"Appareil en charge via USB"</string>
-    <string name="usb_supplying_notification_title" msgid="4631045789893086181">"Rechargement via USB de l\'appareil connecté"</string>
+    <string name="usb_supplying_notification_title" msgid="4631045789893086181">"Recharge via USB de l\'appareil connecté"</string>
     <string name="usb_mtp_notification_title" msgid="4238227258391151029">"Transfert de fichiers via USB activé"</string>
     <string name="usb_ptp_notification_title" msgid="5425857879922006878">"PTP via USB activé"</string>
     <string name="usb_tether_notification_title" msgid="3716143122035802501">"Partage de connexion via USB activé"</string>
     <string name="usb_midi_notification_title" msgid="5356040379749154805">"MIDI via USB activé"</string>
     <string name="usb_accessory_notification_title" msgid="1785694450621427730">"Accessoire USB connecté"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Appuyez ici pour plus d\'options."</string>
-    <string name="usb_power_notification_message" msgid="4647527153291917218">"Rechargement de l\'appareil connecté. Appuyez ici pour plus d\'options."</string>
+    <string name="usb_power_notification_message" msgid="4647527153291917218">"Recharge de l\'appareil connecté. Appuyez ici pour plus d\'options."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Accessoire audio analogique détecté"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"L\'appareil connecté n\'est pas compatible avec ce téléphone. Appuyez ici pour en savoir plus."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correction des couleurs"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Le raccourci d\'accessibilité a activé <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Utilisez à nouveau le raccourci d\'accessibilité pour démarrer la fonctionnalité d\'accessibilité actuelle"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choisissez une fonctionnalité à utiliser lorsque vous appuyez sur le bouton d\'accessibilité :"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pour changer des fonctionnalités, appuyez de manière prolongée sur le bouton d\'accessibilité."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Agrandissement"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ba66adf..4d78073 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Produciuse un problema ao rexistrar as chamadas por wifi co teu operador: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Chamadas por wifi de %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamadas por wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamadas por wifi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wifi preferida"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Datos móbiles preferidos"</string>
@@ -298,8 +302,8 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"facer e xestionar chamadas telefónicas"</string>
     <string name="permgrouprequest_phone" msgid="9166979577750581037">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; realice e xestione chamadas telefónicas?"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder aos datos do sensor sobre as túas constantes vitais"</string>
-    <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda aos datos do sensor sobre as túas constantes vitais?"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder aos datos dos sensores sobre as túas constantes vitais"</string>
+    <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda aos datos dos sensores sobre as túas constantes vitais?"</string>
     <string name="permgrouplab_aural" msgid="965607064083134896">"Música"</string>
     <string name="permgroupdesc_aural" msgid="4870189506255958055">"acceder á música"</string>
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda á túa música?"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Non se recoñeceu"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Autenticouse a impresión dixital"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Autenticouse a cara"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Autenticouse a cara, preme Confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware de impresión dixital non dispoñible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Non se pode almacenar a impresión dixital. Elimina unha impresión dixital existente."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Esgotouse o tempo de espera da impresión dixital. Téntao de novo."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Esgotouse o tempo de espera. Téntao de novo."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Non se puido almacenar a cara."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Cancelouse a operación relacionada coa cara"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"O usuario cancelou a autenticación da cara."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Téntao de novo máis tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiados intentos. Autenticación desactivada."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Téntao de novo."</string>
@@ -934,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>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Corrección de cor"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atallo de accesibilidade activou <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atallo de accesibilidade desactivou <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Para iniciar a función de accesibilidade actual, utiliza de novo o atallo de accesibilidade"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolle que función queres utilizar cando toques o botón Accesibilidade:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar as funcións, mantén premido o botón Accesibilidade."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliación"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 2b96f3f..13090c6 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"તમારા કૅરિઅરમાં વાઇ-ફાઇ કૉલિંગ રજિસ્ટર કરવામાં સમસ્યા આવી: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s વાઇ-ફાઇ કૉલિંગ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ કૉલિંગ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN કૉલ"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN કૉલ"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"વાઇ-ફાઇ કૉલિંગ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"બંધ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"વાઇ-ફાઇ પસંદ કર્યું"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"મોબાઇલને પસંદગી"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ફિંગરપ્રિન્ટ હાર્ડવેર ઉપલબ્ધ નથી."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ફિંગરપ્રિન્ટ સંગ્રહિત કરી શકાતી નથી. કૃપા કરીને અસ્તિત્વમાંની ફિંગરપ્રિન્ટ દૂર કરો."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ફિંગરપ્રિન્ટનો સમય બાહ્ય થયો. ફરી પ્રયાસ કરો."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ચહેરા માટેનો સમય સમાપ્ત થયો. ફરી પ્રયાસ કરો."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ચહેરો સંગ્રહિત કરી શકાશે નહીં."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ચહેરા સંબંધિત કાર્યવાહી રદ કરવામાં આવી છે."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"વપરાશકર્તાએ ચહેરા પ્રમાણીકરણ રદ કર્યુ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ઘણા બધા પ્રયત્નો. થોડા સમય પછી ફરી પ્રયાસ કરો."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ઘણા બધા પ્રયત્નો. ચહેરાનું પ્રમાણીકરણ બંધ કરવામાં આવ્યું છે."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ફરી પ્રયાસ કરો."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"રંગ સુધારણા"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ઍક્સેસિબિલિટી શૉર્ટકટે <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ઍક્સેસિબિલિટી શૉર્ટકટે <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"વર્તમાન ઍક્સેસિબિલિટી સુવિધાને શરૂ કરવા માટે ફરીથી ઍક્સેસિબિલિટી શૉર્ટકટનો ઉપયોગ કરો"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સુવિધા પસંદ કરો:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"સુવિધાઓ બદલવા માટે, ઍક્સેસિબિલિટી બટન દબાવી રાખો."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"વિસ્તૃતીકરણ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6afe603..05ec806 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"वाई-फ़ाई कॉलिंग की सुविधा के लिए आपकी मोबाइल और इंटरनेट सेवा देने वाली कंपनी के साथ रजिस्टर करने से जुड़ी समस्या: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s वाई-फ़ाई कॉलिंग"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई कॉलिंग"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कॉल"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कॉल"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"वाई-फ़ाई कॉलिंग | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाई-फ़ाई को प्राथमिकता"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"मोबाइल को प्राथमिकता"</string>
@@ -514,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>
@@ -523,9 +526,10 @@
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"फ़िंगरप्रिंट हार्डवेयर उपलब्ध नहीं है."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"फ़िंगरप्रिंट को संग्रहित नहीं किया जा सका. कृपया कोई मौजूदा फ़िंगरप्रिंट निकालें."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फ़िंगरप्रिंट का समय समाप्त हो गया. पुनः प्रयास करें."</string>
@@ -562,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"चेहरे की पहचान का समय खत्म हुआ. फिर से कोशिश करें."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"चेहरा सेव करने की सीमा पूरी हो गई है."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"चेहरा पहचानने की कार्रवाई रद्द की गई."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"उपयोगकर्ता ने चेहरे की पहचान रद्द कर दी."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"कई बार कोशिश की गई. बाद में कोशिश करें."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"कई बार कोशिश की. चेहरा पहचानने की सुविधा बंद हुई."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"फिर से कोशिश करें."</string>
@@ -1618,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"रंग में सुधार करने की सुविधा"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"सुलभता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू किया"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"सुलभता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद किया"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"मौजूदा सुलभता सुविधा शुरू करने के लिए \'सुलभता शॉर्टकट\' का फिर से इस्तेमाल करें"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"सुलभता बटन पर टैप करते समय इस्तेमाल की जाने वाली सुविधा चुनें:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाओं में बदलाव करने के लिए, सुलभता बटन को दबाकर रखें."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"बड़ा करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index e7b6b5f..839d423 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -129,10 +129,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Poteškoća s registracijom Wi‑Fi poziva kod mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi pozivanje"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi pozivi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Poziv putem WLAN-a"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> poziv putem WLAN-a"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi pozivi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi mreža"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Za mobilne uređaje"</string>
@@ -527,6 +531,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nije prepoznato"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Autentificirano otiskom prsta"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Lice je autentificirano"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Lice je autentificirano, pritisnite Potvrdi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardver za otisak prsta nije dostupan."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Otisak prsta nije pohranjen. Uklonite postojeći otisak prsta."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Isteklo je vrijeme čekanja za otisak prsta. Pokušajte ponovo."</string>
@@ -563,6 +569,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Isteklo je vrijeme čekanja za lice. Pokušajte opet"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Nije moguće pohraniti lice."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Otkazana je radnja s licem."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentifikaciju lica otkazao je korisnik."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Previše pokušaja. Autentifikacija lica onemogućena"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Pokušajte ponovo."</string>
@@ -1640,6 +1647,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korekcija boje"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečac pristupačnosti uključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečac pristupačnosti isključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Ponovo upotrijebite prečac pristupačnosti da biste pokrenuli trenutačnu značajku pristupačnosti"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Odaberite značajku koju ćete upotrebljavati kada dodirnete gumb Pristupačnost:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da biste promijenili značajke, dodirnite i zadržite gumb Pristupačnost."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Povećavanje"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3d9a35b..bc54bfa 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Hiba történt a Wi‑Fi-hívás szolgáltatónál való regisztrálása során: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi-hívás"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-hívás"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-hívás"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-hívás"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-hívás | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ki"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi előnyben részesítve"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferált: mobil"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nem ismerhető fel"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Ujjlenyomat hitelesítve"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Arc hitelesítve"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Arc hitelesítve; nyomja meg a Megerősítés lehetőséget"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Az ujjlenyomathoz szükséges hardver nem érhető el."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Az ujjlenyomat nem tárolható. Távolítson el egy meglévő ujjlenyomatot."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Az ujjlenyomat-beolvasási műveletkor időtúllépés történt. Próbálkozzon újra."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Időtúllépés az arcbeolvasásnál. Próbálja újra."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Az arc nem tárolható."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Az arccal kapcsolatos művelet törölve."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Az arc hitelesítését a felhasználó visszavonta."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Túl sok próbálkozás. Próbálja újra később."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Túl sok próbálkozás. Arcfelismerés letiltva."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Próbálkozzon újra."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Színkorrekció"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"A Kisegítő lehetőségek gyorsparancsa bekapcsolta a következő szolgáltatást: <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"A Kisegítő lehetőségek gyorsparancsa kikapcsolta a következő szolgáltatást: <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Használja újból a Kisegítő lehetőségek gyorsparancsát az aktuális kisegítő lehetőségek elindításához"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Válassza ki a Kisegítő lehetőségek gombra koppintáskor használni kívánt funkciót:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"A funkciók módosításához tartsa lenyomva a Kisegítő lehetőségek gombot."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Nagyítás"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 6a5f287..4a828fa 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Wi‑Fi-ի միջոցով արվող զանգերը չհաջողվեց գրանցել ձեր օպերատորի մոտ՝ <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi զանգեր"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-ի միջոցով զանգեր"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Զանգ WLAN ցանցով"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ցանցով զանգեր"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Զանգեր Wi-Fi-ի միջոցով | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Անջատված է"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi, նախընտրելի"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Նախընտրելի է բջջային ցանցը"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Մատնահետքի սարքն անհասանելի է:"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Հնարավոր չէ պահել մատնահետքը: Հեռացրեք առկա մատնահետքը:"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Մատնահետքի գրանցման ժամանակը սպառվել է: Փորձեք նորից:"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Ժամանակը սպառվել է: Նորից փորձեք:"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Դեմքը հնարավոր չէ պահել։"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Դեմքի ճանաչումը չեղարկվել է։"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Դեմքի ճանաչումը չեղարկվել է օգտատիրոջ կողմից:"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Չափից շատ փորձեր եք կատարել: Փորձեք ավելի ուշ:"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Չափից շատ փորձեր եք կատարել: Դեմքի ճանաչման գործառույթն անջատվել է։"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Նորից փորձեք:"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Գունաշտկում"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Մատչելիության դյուրանցումն միացրել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Մատչելիության դյուրանցումն անջատել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Հատուկ գործառույթների դյուրանցումը գործարկելու համար նորից օգտագործեք համապատասխան դյուրանցումը"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Ընտրեք որևէ գործառույթ, որը կօգտագործվի Հատուկ գործառույթներ կոճակին հպելու դեպքում՝"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Գործառույթները փոխելու համար հպեք և պահեք Հատուկ գործառույթներ կոճակը։"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Խոշորացում"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 6d1da48..167082d 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Terjadi masalah saat mendaftarkan panggilan Wi‑Fi dengan operator Anda: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Panggilan Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Panggilan WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Panggilan WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Panggilan WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Nonaktif"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi dipilih"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Seluler dipilih"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Tidak dikenali"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Sidik jari diautentikasi"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Wajah diautentikasi"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Wajah diautentikasi, silakan tekan konfirmasi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware sidik jari tidak tersedia."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Sidik jari tidak dapat disimpan. Hapus sidik jari yang ada."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Waktu sidik jari habis. Coba lagi."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Waktu tunggu wajah habis. Harap coba lagi."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Wajah tidak dapat disimpan."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Pemrosesan wajah dibatalkan."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentikasi wajah dibatalkan oleh pengguna."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Terlalu banyak percobaan. Coba lagi nanti."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Terlalu sering dicoba. Autentikasi wajah dinonaktifkan."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Coba lagi."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Koreksi Warna"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pintasan Aksesibilitas mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pintasan Aksesibilitas menonaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Gunakan Pintasan Aksesibilitas lagi untuk memulai fitur aksesibilitas saat ini"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pilih fitur yang akan digunakan saat menge-tap tombol Aksesibilitas:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Untuk mengubah fitur, sentuh &amp; tahan tombol Aksesibilitas."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pembesaran"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 4d7996f..0c7e6b8 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Vandamál kom upp við að skrá Wi‑Fi símtöl hjá símafyrirtækinu: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi símtöl"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi símtöl"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-símtal"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-símtal"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi símtal | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Slökkt"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi í forgangi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Farsímakerfi í forgangi"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Þekktist ekki"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingrafar staðfest"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Andlit staðfest"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Andlit staðfest, ýttu til að staðfesta"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingrafarsvélbúnaður ekki til staðar."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Ekki er hægt að vista fingrafarið. Fjarlægðu eitthvert af fingraförunum sem fyrir eru."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Tímamörk runnu út fyrir andlit. Reyndu aftur."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Ekki tókst að geyma andlit."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Hætt við andlitsgreiningu."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Notandi hætti við andlitsgreiningu."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Of margar tilraunir. Reyndu aftur síðar."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Of margar tilraunir. Slökkt á andlitsgreiningu."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Reyndu aftur."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Litaleiðrétting"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Flýtileið aðgengisstillingar kveikti á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Flýtileið aðgengisstillingar slökkti á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Notaðu flýtileið aðgengisstillingar aftur til að opna aðgengiseiginleika"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Veldu eiginleika sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Haltu fingri á aðgengishnappinum til að breyta eiginleikum."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Stækkun"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 44818a3..a6d5d23 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Si è verificato un problema con la registrazione delle chiamate Wi‑Fi con l\'operatore: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Chiamata Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chiamate Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chiamata WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chiamata WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chiamate Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Non attiva"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Rete preferita: Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Rete preferita: dati mobili"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Non riconosciuto"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impronta digitale autenticata"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Volto autenticato"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Volto autenticato, premi Conferma"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware per l\'impronta digitale non disponibile."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Impossibile memorizzare l\'impronta digitale. Rimuovi un\'impronta esistente."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta digitale. Riprova."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Timeout operazione associata al volto. Riprova."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Il volto non può essere memorizzato."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operazione associata al volto annullata."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticazione del volto annullata dall\'utente."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Troppi tentativi. Riprova più tardi."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Troppi tentativi. Autenticazione disattivata."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Riprova."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correzione del colore"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"La scorciatoia Accessibilità ha attivato <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"La scorciatoia Accessibilità ha disattivato <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Usa di nuovo la scorciatoia Accessibilità per avviare l\'attuale funzione di accessibilità"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Scegli una funzione da usare quando tocchi il pulsante Accessibilità:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Per cambiare le funzioni, tocca e tieni premuto il pulsante Accessibilità."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ingrandimento"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index fd5c2a1..48933f9 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"‏אירעה בעיה ברישום שיחות Wi-Fi אצל הספק שלך: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"‏שיחות Wi-Fi של %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏שיחות Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"שיחה ברשת אלחוטית"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏שיחת WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"‏שיחות WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"כבוי"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏Wi-Fi מועדף"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"מצב מועדף: רשת סלולרית"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"החומרה בשביל טביעת אצבע אינה זמינה."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"לא ניתן לאחסן טביעת אצבע. הסר טביעת אצבע קיימת."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"חלף הזמן הקצוב לטביעת אצבע. נסה שוב."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"חלף הזמן הקצוב לזיהוי הפנים. יש לנסות שוב."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"לא ניתן לשמור את הפנים."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"פעולת הפנים בוטלה."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"זיהוי הפנים בוטל על ידי המשתמש."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"יותר מדי ניסיונות. יש לנסות שוב מאוחר יותר."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"יותר מדי ניסיונות. אימות הפנים הושבת."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"יש לנסות שוב."</string>
@@ -1228,13 +1235,13 @@
     <string name="volume_call" msgid="3941680041282788711">"עוצמת קול בשיחה"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"‏עוצמת הקול בשיחה ב-Bluetooth"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"עוצמת קול של התראה"</string>
-    <string name="volume_notification" msgid="2422265656744276715">"עוצמת קול של הודעות"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"עוצמת הקול של ההתראות"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"עוצמת קול"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"‏עוצמת קול של Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"עוצמת קול של רינגטון"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"עוצמת קול של שיחות"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"עוצמת קול של מדיה"</string>
-    <string name="volume_icon_description_notification" msgid="7044986546477282274">"עוצמת קול של הודעות"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"עוצמת הקול של ההתראות"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"רינגטון ברירת מחדל"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"ברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="7937634392408977062">"ללא"</string>
@@ -1502,7 +1509,7 @@
     <string name="sync_really_delete" msgid="2572600103122596243">"מחק את הפריטים"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"בטל את פעולות המחיקה"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"אל תעשה דבר כרגע"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"בחר חשבון"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"בחירת חשבון"</string>
     <string name="add_account_label" msgid="2935267344849993553">"הוספת חשבון"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"הוספת חשבון"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"הוסף"</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"תיקון צבעים"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל על-ידי קיצור הדרך לנגישות"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת על-ידי קיצור הדרך לנגישות"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"יש להשתמש שוב במקש הקיצור לנגישות כדי להפעיל את תכונת הנגישות הנוכחית"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"בחר תכונה שתופעל כשתלחץ על הלחצן \'נגישות\':"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"כדי להחליף תכונה, גע בלחצן \'נגישות\' והחזק אותו."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"הגדלה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4915111..994039c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"携帯通信会社への Wi‑Fi 通話の登録中に問題が発生しました(<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Wi-Fi通話(%s)"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi 通話 | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"OFF"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi優先"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"モバイル優先"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"指紋ハードウェアは使用できません。"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"指紋を保存できません。既存の指紋を削除してください。"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"読み取りのタイムアウトです。もう一度お試しください。"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"顔の情報を保存できません。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"顔の操作をキャンセルしました。"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"顔の認証がユーザーによりキャンセルされました。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"試行回数の上限です。後でもう一度お試しください。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"試行回数の上限です。顔認証は無効になりました。"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"もう一度お試しください。"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"色補正"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ユーザー補助機能のショートカットにより <xliff:g id="SERVICE_NAME">%1$s</xliff:g> は ON になっています"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ユーザー補助機能のショートカットにより <xliff:g id="SERVICE_NAME">%1$s</xliff:g> は OFF になっています"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"現在のユーザー補助機能を開始するには、ユーザー補助機能のショートカットをもう一度使用してください"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"[ユーザー補助] ボタンをタップした場合に使用する機能を選択してください。"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"機能を変更するには、[ユーザー補助] ボタンを押し続けてください。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"拡大"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 51a4c28..a9ce748 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Wi‑Fi დარეკვის თქვენს ოპერატორთან რეგისტრირებისას შეცდომა წარმოიქმნა: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s დარეკვა Wi-Fi-ს მეშვეობით"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi დარეკვა"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ზარი"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ზარი"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi დარეკვა | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"გამორთული"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"სასურველია Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"უპირატესობა მიენიჭოს მობილურს"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"თითის ანაბეჭდის აპარატურა არ არის ხელმისაწვდომი."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"თითის ანაბეჭდის შენახვა ვერ ხერხდება. გთხოვთ, ამოშალოთ არსებული თითის ანაბეჭდი."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"თითის ანაბეჭდის ლოდინის დრო ამოიწურა. სცადეთ ხელახლა."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"სახის ამოცნობის დრო ამოიწურა. ცადეთ ხელახლა."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"სახის შენახვა ვერ მოხერხდა."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"სახის ამოცნობა გაუქმდა."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"სახის ავტორიზაცია გაუქმდა მომხმარებლის მიერ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"დაფიქსირდა ბევრი მცდელობა. ცადეთ მოგვიანებით."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"დაფიქსირდა ბევრი მცდელობა. სახის ამოცნობა გაითიშა."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ცადეთ ხელახლა."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ფერთა კორექცია"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"მარტივი წვდომის მალსახმობმა ჩართო <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"მარტივი წვდომის მალსახმობმა გამორთო <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"მარტივი წვდომის ამჟამინდელი ფუნქციის გასაშვებად გამოიყენეთ მარტივი წვდომის მალსახმობი"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი ფუნქცია:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ფუნქციების შესაცვლელად ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"გადიდება"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 18be1e6..a8b527b 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Оператордың Wi‑Fi қоңырауын тіркеу кезінде қате шықты: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi арқылы қоңырау шалу"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi қоңыраулары"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN қоңырауы"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN қоңырауы"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi қоңыраулары | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Өшірулі"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Қалаулы Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Таңдаулы мобильдік байланыс"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Саусақ ізі жабдығы қолжетімді емес."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Саусақ ізін сақтау мүмкін емес. Бар саусақ ізін жойыңыз."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Саусақ ізін күту уақыты бітті. Әрекетті қайталаңыз."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Күту уақыты бітті. Әрекетті қайталаңыз."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Бетті сақтау мүмкін емес."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Бетті танудан бас тартылды."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Пайдаланушы бетті тану әрекетінен бас тартты."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Тым көп әрекет жасалды. Кейінірек қайталаңыз."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Тым көп әрекет жасалды. Бетті тану функциясы өшірілді."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Қайталап көріңіз."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Түсті түзету"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Арнайы мүмкіндіктер таңбашасы <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосты"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Арнайы мүмкіндіктер таңбашасы <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін өшірді"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Арнайы мүмкіндіктер функциясын іске қосу үшін оның таңбашасын пайдаланыңыз"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын мүмкіндікті таңдаңыз:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Мүмкіндіктерді өзгерту үшін \"Арнайы мүмкіндіктер\" түймесін түртіп, ұстап тұрыңыз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ұлғайту"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 091fa71..2620ce4 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"មាន​បញ្ហា​ក្នុង​ការ​ចុះ​ឈ្មោះ​ការហៅ​តាម Wi‑Fi ជាមួយ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​របស់អ្នក៖ <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"ការហៅតាមរយៈ Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ការហៅតាម Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"ការហៅ​តាម WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> ការហៅតាម WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ការហៅតាម WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"បិទ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ជាអាទិភាព"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ទិន្នន័យទូរសព្ទចល័តជាអាទិភាព"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ផ្នែករឹងស្នាមម្រាមដៃមិនមានទេ។"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"មិនអាចផ្ទុកស្នាមម្រាមដៃទេ។ សូមយកស្នាមម្រាមដៃដែលមានស្រាប់ចេញ។"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ការផ្តិតម្រាមដៃបានអស់ពេល។ សូមព្យាយាមម្តងទៀត។"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ការសម្គាល់​ផ្ទៃមុខ​បាន​អស់ម៉ោង។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"មិន​អាច​រក្សាទុក​ផ្ទៃ​មុខ​បានទេ។"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"បាន​បោះបង់​ប្រតិបត្តិការចាប់​ផ្ទៃមុខ។"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ការផ្ទៀងផ្ទាត់​មុខ​ត្រូវបានបោះបង់ដោយអ្នកប្រើប្រាស់។"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ព្យាយាមចូលច្រើនពេកហើយ។ បាន​បិទការផ្ទៀងផ្ទាត់​ផ្ទៃ​មុខ។"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"សូមព្យាយាម​ម្ដងទៀត។"</string>
@@ -1618,6 +1625,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ការ​កែ​ពណ៌"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ផ្លូវកាត់​ភាព​ងាយ​ស្រួល​បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ផ្លូវកាត់​ភាព​ងាយ​ស្រួល​បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ប្រើផ្លូវកាត់​ភាពងាយស្រួល​ម្ដងទៀត ដើម្បី​ចាប់ផ្ដើម​មុខងារ​ភាពងាយប្រើ​បច្ចុប្បន្ន"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ជ្រើសរើស​មុខងារ​ដែលត្រូវ​ប្រើ នៅពេល​ដែល​អ្នកចុច​ប៊ូតុង​ភាពងាយស្រួល៖"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ដើម្បី​ផ្លាស់ប្តូរ​មុខងារ សូម​ចុច​ប៊ូតុង​ភាព​ងាយស្រួល​ឲ្យ​ជាប់។"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ការ​ពង្រីក"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index e228d35..1b83ec2 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"ನಿಮ್ಮ ವಾಹಕದೊಂದಿಗೆ ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ ಸಮಸ್ಯೆ ನೋಂದಾಯಿಸುವಿಕೆ: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ಕರೆ"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ಕರೆ"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ವೈಫೈ ಕರೆಮಾಡುವಿಕೆ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ಆಫ್"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ವೈ-ಫೈಗೆ ಆದ್ಯತೆ"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ಮೊಬೈಲ್‌ಗೆ ಆದ್ಯತೆ"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ಬೆರಳಚ್ಚು ಹಾರ್ಡ್‌ವೇರ್‌ ಲಭ್ಯವಿಲ್ಲ."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ಬೆರಳಚ್ಚು ಸಂಗ್ರಹಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಬೆರಳಚ್ಚು ತೆಗೆದುಹಾಕಿ."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ಬೆರಳಚ್ಚು ಅವಧಿ ಮೀರಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ಮುಖ ಸಮಯದ ಅವಧಿಯನ್ನು ತಲುಪಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ಮುಖವನ್ನು ಸಂಗ್ರಹಿಸಲಾಗುವುದಿಲ್ಲ."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ಮುಖದ ಕಾರ್ಯಚರಣೆಯನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ಮುಖ ದೃಢೀಕರಣವನ್ನು ಬಳಕೆದಾರರ ಮೂಲಕ ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ಹಲವು ಪ್ರಯತ್ನ. ಮುಖದ ದೃಢೀಕರಣ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ಬಣ್ಣ ತಿದ್ದುಪಡಿ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಿದೆ"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಫ್ ಮಾಡಿದೆ"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ಪ್ರಸ್ತುತ ಪ್ರವೇಶದ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಪ್ರಾರಂಭಿಸಲು ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌ ಅನ್ನು ಪುನಃ ಬಳಸಿ"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ನೀವು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಆರಿಸಿ:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬದಲಾಯಿಸಲು, ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಒತ್ತಿಹಿಡಿದುಕೊಳ್ಳಿ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d37a475..6223dab 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"이동통신사를 통해 Wi‑Fi 통화를 등록하는 중에 문제가 발생했습니다. 오류 코드: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi 통화"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 통화"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 통화"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 통화"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi 통화 | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"꺼짐"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi를 기본으로 설정"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"모바일에 최적화됨"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"지문 인식 하드웨어를 사용할 수 없습니다."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"지문을 저장할 수 없습니다. 기존 지문을 삭제하세요."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"지문 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"얼굴 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"얼굴을 저장할 수 없습니다."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"얼굴 인식 작업이 취소되었습니다."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"사용자가 얼굴 인증을 취소했습니다."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"시도 횟수가 너무 많아 얼굴 인증이 사용 중지되었습니다."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"다시 시도해 보세요."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"색상 보정"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"접근성 단축키로 인해 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"접근성 단축키로 인해 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"현재 접근성 기능을 시작하려면 접근성 단축키를 다시 사용하세요"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"접근성 버튼을 탭할 때 사용할 기능을 선택하세요."</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"기능을 변경하려면 접근성 버튼을 길게 터치하세요."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"확대"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index cf5f531..f49746f 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Байланыш операторуңуз менен Wi-Fi аркылуу чалууну каттоодо ката кетти: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Чалуу"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi аркылуу чалуу"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN аркылуу чалуу"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN аркылуу чалуу"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi аркылуу чалуу | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Өчүк"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi тандалган"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Тандалган мобилдик түзмөк"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Манжа изинин аппараттык камсыздоосу жеткиликтүү эмес."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Манжа изин сактоо мүмкүн эмес. Учурдагы манжа изин алып салыңыз."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Манжа изин күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Жүздүн аныктыгын текшерүүнү күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Жүздү сактоо мүмкүн эмес."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Жүздүн аныктыгын текшерүү жокко чыгарылды."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Жүздүн аныктыгын текшерүү колдонуучу аркылуу жокко чыгарылды."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Өтө көп жолу аракет жасадыңыз. Кийинчерээк кайра аракет кылыңыз."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Өтө көп жолу аракет жасадыңыз. Жүздүн аныктыгын текшерүү сенсору өчүрүлдү."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Кайра аракет кылыңыз."</string>
@@ -1618,6 +1625,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Түсүн тууралоо"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүздү"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын өчүрдү"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Учурдагы атайын мүмкүнчүлүктөр функциясын иштетүү үчүн кыска жолду кайра колдонуңуз"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштетиле турган функцияны тандаңыз:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Функцияларды өзгөртүү үчүн Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Чоңойтуу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 7d8a4e2..9fc6033 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"ເກີດບັນຫາໃນການລົງທະບຽນການໂທ Wi‑Fi ກັບຜູ້ໃຫ້ບໍລິການຂອງທ່ານ: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"ການ​ໂທ %s Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Call"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ປິດ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ເລືອກໃຊ້ Wi​-Fi ກ່ອນ"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ຕ້ອງການໃຊ້ມືຖື"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ບໍ່​ມີ​ຮາດ​ແວລາຍ​ນີ້ວ​ມື​ໃຫ້​ຢູ່."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ບໍ່​ສາ​ມາດ​ເກັບ​ຮັກ​ສາ​ລາຍ​ນີ້ວ​ມື​ໄວ້​ໄດ້. ກະ​ລຸ​ນາ​ເອົາ​ລາຍ​ນີ້ວ​ມື​ທີ່​ມີ​ຢູ່​ອອກ​ໄປ."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ເວ​ລາ​ລາຍ​ນີ້ວ​ມື​ບໍ່​ເຂົ້າ​ເຖິງ​ໄດ້. ລອງ​ໃໝ່​ອີກ."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ໝົດເວລາກວດໃບໜ້າແລ້ວ. ກະລຸນາລອງອີກຄັ້ງ."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ບໍ່ສາມາດເກັບຮັກສາໃບໜ້າໄວ້ໄດ້."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ຍົກເລີກການດຳເນີນການກັບໃບໜ້າແລ້ວ."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ຜູ້ໃຊ້ຍົກເລີກການພິສູດຢືນຢັນໃບໜ້າແລ້ວ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ປິດນຳໃຊ້ການກວດສອບຄວາມຖືກຕ້ອງດ້ວຍໃບໜ້າແລ້ວ."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ລອງອີກຄັ້ງ."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ການແກ້ໄຂຄ່າສີ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ໃຊ້ປຸ່ມລັດການຊ່ວຍເຂົ້າເຖິງອີກເທື່ອໜຶ່ງເພື່ອຊອກຫາຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງໃນປັດຈຸບັນ"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ເລືອກຄຸນສົມບັດທີ່ຈະໃຊ້ເມື່ອທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ເພື່ອປ່ຽນຄຸນສົມບັດ, ໃຫ້ແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ການຂະຫຍາຍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index a0015c3..f1dc8d1 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Kilo problema registruojant „Wi‑Fi“ skambinimą pas operatorių: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"„%s“ „Wi-Fi“ skambinimas"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“ skambinimas"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN skambutis"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN skambutis"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"„Wi-Fi“ skambinimas | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> „VoWifi“"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Išjungta"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Pageidautinas „Wi-Fi“ ryšys"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Pirmenybė mobiliojo ryšio tinklui"</string>
@@ -322,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>
@@ -502,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>
@@ -521,29 +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_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_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">"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>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Baigėsi veido atpaž. skirt. laik. Band. dar kartą."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Nepavyko išsaugoti veido duomenų."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Veido atpažinimo operacija atšaukta."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Veido autentifikavimą atšaukė naudotojas."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Per daug bandymų. Veido autentifik. išjungtas."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Bandykite dar kartą."</string>
@@ -1573,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>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Spalvų taisymas"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pritaikymo neįgaliesiems sparčiuoju klavišu buvo įjungta „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pritaikymo neįgaliesiems sparčiuoju klavišu buvo išjungta „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Norėdami įjungti dabartinę pritaikymo neįgaliesiems funkciją, dar kartą naudokite spartųjį pritaikymo neįgaliesiems klavišą"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pasirinkite funkciją, kuri bus naudojama, kai paliesite pritaikymo neįgaliesiems mygtuką:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Jei norite pakeisti funkcijas, palieskite ir palaikykite pritaikymo neįgaliesiems mygtuką."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Didinimas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index a1aebe1..156a1a9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -129,10 +129,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Reģistrējot Wi-Fi zvanus pie mobilo sakaru operatora, radās problēma: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi zvani"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi zvani"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN zvans"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN zvans"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi zvani | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Izslēgts"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Vēlams Wi-Fi tīkls"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Vēlams mobilo datu savienojums"</string>
@@ -527,6 +531,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Dati nav atpazīti"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Pirksta nospiedums tika autentificēts."</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Seja autentificēta"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Seja ir autentificēta. Nospiediet pogu Apstiprināt."</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Nospieduma aparatūra nav pieejama."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Pirkstu nospiedumu nevar saglabāt. Lūdzu, noņemiet esošu pirksta nospiedumu."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Pirkstu nospiedumu nolasīšanas aparatūras noildze. Mēģiniet vēlreiz."</string>
@@ -563,6 +569,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Sejas datu nolasīšanas noildze. Mēģiniet vēlreiz."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Sejas datus nevar saglabāt."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Darbība ar sejas datiem atcelta."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Lietotājs atcēla sejas autentificēšanu."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Par daudz mēģinājumu. Sejas atpazīšana atspējota."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Mēģiniet vēlreiz."</string>
@@ -1640,6 +1647,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Krāsu korekcija"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pieejamības saīsne aktivizēja lietotni <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pieejamības saīsne deaktivizēja lietotni <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Lai sāktu izmantot pašreizējo pieejamības funkciju, vēlreiz izmantojiet pieejamības saīsni."</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pogai Pieejamība."</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Lai mainītu funkcijas, pieskarieties pogai Pieejamība un turiet to."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Palielinājums"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0ab31b3..8bca75e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Проблем при регистрирањето на функцијата „Повици преку Wi‑Fi“ со операторот: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Повикување преку Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Повик преку WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Повик преку WLAN на <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Повици преку Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"Глас преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Исклучено"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Се претпочита Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Претпочитам мобилен интернет"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Хардвер за отпечаток од прст не е достапен."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Отпечатокот не може да се складира. Отстранете го постоечкиот отпечаток."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Се достигна времето на истекување на отпечатокот. Обидете се повторно."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Истече времето за проверка на лице. Повторен обид."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Лицето не може да се чува."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Операцијата со лице се откажа."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Проверката на лицето е откажана од корисникот."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Премногу обиди. Обидете се повторно подоцна."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Премногу обиди. Проверката на лице е оневозможена."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Обидете се повторно."</string>
@@ -1619,6 +1626,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Корекција на бои"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Кратенката за пристапност ја вклучи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Кратенката за пристапност ја исклучи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Повторно употребете ја кратенката за пристапност за да ја стартувате тековната функција за пристапност"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изберете функција за користење кога ќе го допрете копчето за „Пристапност“."</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"За променување функции, допрете го и задржете го копчето за „Пристапност“."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Зголемување"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index eafd6a4..1efdc72 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"നിങ്ങളുടെ കാരിയർ ഉപയോഗിച്ച് വൈഫൈ കോളിംഗ് രജിസ്‌റ്റർ ചെയ്യുന്നതിൽ പ്രശ്‌നം: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s വൈഫൈ കോളിംഗ്"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ കോളിംഗ്"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN കോൾ"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN കോൾ"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"വൈഫൈ കോളിംഗ് | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> Voവൈഫൈ"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ഓഫ്"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"വൈഫൈ തിരഞ്ഞെടുത്തിരിക്കുന്നു"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"മൊബൈൽ ഡാറ്റ ഉപയോഗിക്കാൻ താൽപ്പര്യപ്പെടുന്നു"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ഫിംഗർപ്രിന്റ് ഹാർഡ്‌വെയർ ലഭ്യമല്ല."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"വിരലടയാളം സംഭരിക്കാനാവില്ല. നിലവിലുള്ള വിരലടയാളം നീക്കംചെയ്യുക."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"വിരലടയാളം നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"മുഖം നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"മുഖം സൂക്ഷിക്കാനാവില്ല."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"മുഖത്തിന്റെ പ്രവർത്തനം റദ്ദാക്കി."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"മുഖം പരിശോധിച്ചുറപ്പിക്കൽ ഉപയോക്താവ് റദ്ദാക്കി."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"നിരവധി തവണ ശ്രമിച്ചു. മുഖം തിരിച്ചറിയൽ പ്രവർത്തനരഹിതമാക്കി."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"വീണ്ടും ശ്രമിക്കുക."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"വർണ്ണം ക്രമീകരിക്കൽ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ഉപയോഗസഹായിക്കുള്ള കുറുക്കുവഴി <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓൺ ചെയ്തിരിക്കുന്നു"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ഉപയോഗസഹായിക്കുള്ള കുറുക്കുവഴി <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫ് ചെയ്തിരിക്കുന്നു"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"നിലവിലെ ഉപയോഗസഹായി ഫീച്ചർ ആരംഭിക്കാൻ വീണ്ടും ഉപയോഗസഹായി കുറുക്കുവഴി ഉപയോഗിക്കുക"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പുചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ഫീച്ചറുകൾ മാറ്റുന്നതിന് ഉപയോഗസഹായി ബട്ടൺ സ്‌പർശിച്ചുപിടിക്കുക."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"മാഗ്നിഫിക്കേഷൻ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 12e3186..86ae178 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Таны оператор компанийн Wi‑Fi дуудлагыг бүртгэхэд асуудал гарлаа: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi Дуудлага"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi дуудлага"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN дуудлага"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN дуудлага"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi дуудлага | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Идэвхгүй"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi давуу эрхтэй"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Мобайл давуу эрхтэй"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Хурууны хээний тоног төхөөрөмж бэлэн бус байна."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Хурууны хээг хадгалах боломжгүй байна. Одоо байгаа хурууны хээг арилгана уу."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Хурууны хээ оруулах хугацаа өнгөрсөн байна. Дахин оруулна уу."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Царай таниулах хугацаа дууслаа. Дахин оролдоно уу."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Царайг хадгалах боломжгүй байна."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Царайны үйл ажиллагааг цуцаллаа."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Хэрэглэгч царайгаар баталгаажуулахыг цуцалсан байна."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Хэт олон удаа оролдлоо. Дараа дахин оролдоно уу."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Хэт олон удаа оролдлоо. Царай танилтыг идэвхгүй болголоо."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Дахин оролдоно уу."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Өнгөний засвар"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Хүртээмжийн товчлол <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаасан"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Хүртээмжийн товчлол <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраасан"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Одоогийн хүртээмжит онцлогийг эхлүүлэхийн тулд нэвтрэлтийн товчлолыг ашиглах"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Хүртээмжийн товчлуурыг товших үедээ ашиглах онцлогийг сонгоно уу:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Онцлогийг өөрчлөхийн тулд Хүртээмжийн товчлуурыг дараад хүлээнэ үү."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Томруулах"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index fe248c1..70ed012 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"तुमच्या या वाहकासह वाय-फाय कॉलिंग नोंदणी करताना समस्या आली आहे:<xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s वाय-फाय कॉलिंग"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय कॉलिंग"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कॉल"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कॉल"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"वाय-फाय कॉलिंग | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाय-फाय अग्रमानांकित"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"प्राधान्य दिलेला मोबाइल"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"फिंगरप्रिंट हार्डवेअर उपलब्‍ध नाही."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"फिंगरप्रिंट स्टोअर केले जाऊ शकत नाही. कृपया विद्यमान फिंगरप्रिंट काढा."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फिंगरप्रिंट टाइमआउट झाले. पुन्हा प्रयत्न करा."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"चेहरा टाइमआउट झाला. पुन्हा प्रयत्न करा."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"चेहरा स्टोअर केला जाऊ शकत नाही."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"चेहरा ऑपरेशन रद्द केले गेले."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"वापरकर्त्याने चेहरा ऑथेंटिकेशन रद्द केले."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"खूप जास्त प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"खूप जास्त प्रयत्न केले. चेहरा ऑथेंटिकेशन बंद केले गेले."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"पुन्हा प्रयत्न करा."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"रंग सुधारणा"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> चालू केली"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केली"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"सध्याचे अॅक्सेसिबिलिटी वैशिष्‍ट्य पुन्हा सुरू करण्‍यासाठी अॅक्सेसिबिलिटी शॉर्टकट वापरा"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"तुम्ही प्रवेशयोग्यता बटण दाबल्यावर वापरण्यासाठी वैशिष्ट्य निवडा:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"वैशिष्ट्ये बदलण्यासाठी, प्रवेशयोग्यता बटणाला स्पर्श करा आणि धरून ठेवा."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"मोठे करणे"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a813a7b..208fed6 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Terdapat masalah semasa mendaftarkan panggilan Wi-Fi dengan pembawa anda: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Panggilan Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Panggilan WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Panggilan WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Panggilan Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Mati"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi diutamakan"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mudah alih diutamakan"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Tidak dikenali"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Cap jari disahkan"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Wajah disahkan"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Wajah disahkan, sila tekan sahkan"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Perkakasan cap jari tidak tersedia."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Cap jari tidak dapat disimpan. Sila alih keluar cap jari sedia ada."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tamat masa cap jari dicapai. Cuba lagi."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Tamat masa wajah dicapai. Cuba lagi."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Wajah tidak dapat disimpan."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Pengendalian wajah dibatalkan."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Pengesahan wajah dibatalkan oleh pengguna."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Terlalu banyak percubaan. Pengesahan wajah dilumpuhkan."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Cuba lagi."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Pembetulan Warna"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pintasan kebolehaksesan menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pintasan Kebolehaksesan mematikan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Gunakan Pintasan Kebolehaksesan sekali lagi untuk memulakan ciri kebolehaksesan semasa"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pilih ciri yang hendak digunakan apabila anda mengetik butang Kebolehaksesan:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Untuk menukar ciri, sentuh &amp; tahan butang Kebolehaksesan."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pembesaran"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 812ff75..71dd4b6 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"သင်၏ ဝန်ဆောင်မှုပေးသူဖြင့် Wi‑Fi ခေါ်ဆိုမှုကို မှတ်ပုံတင်ရာတွင် ပြဿနာရှိနေသည်− <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi  ခေါ်ဆိုမှု"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi ခေါ်ဆိုမှု"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ခေါ်ဆိုမှု"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ခေါ်ဆိုမှု"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi ခေါ်ဆိုမှု | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ပိတ်ထားရသည်"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ဝိုင်ဖိုင်အား ပိုနှစ်သက်သော"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"မိုဘိုင်းကို အသုံးပြုလိုပါသည်"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"လက်ဗွေရာ ဟာ့ဒ်ဝဲ မရနိုင်ပါ။"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"လက်ဗွေရာ သိုလှောင်၍မရပါ။ ကျေးဇူးပြု၍ ရှိပြီးလက်ဗွေရာအား ဖယ်ရှားပါ။"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"လက်ဗွေရာအချိန်ကုန် သွားပါသည်။ ထပ်မံကြိုးစားပါ။"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"မျက်နှာ သက်တမ်းကုန်သွားပါပြီ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"မျက်နှာကို သိမ်း၍မရပါ။"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"မျက်နှာ ဆောင်ရွက်ခြင်းကို ပယ်ဖျက်လိုက်ပါပြီ။"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"အသုံးပြုသူက မျက်နှာအထောက်အထားစိစစ်မှု မလုပ်တော့ပါ။"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"အကြိမ်များစွာ စမ်းပြီးပါပြီ။ နောက်မှထပ်စမ်းပါ။"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"အကြိမ်များစွာ စမ်းပြီးပါပြီ။ ပိတ်လိုက်ပါပြီ။"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ထပ်စမ်းကြည့်ပါ။"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"အရောင်ပြင်ဆင်ခြင်း"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်သည် <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို ဖွင့်လိုက်ပါသည်"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်သည် <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို ပိတ်လိုက်ပါသည်"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"လက်ရှိ အသုံးလွယ်ရေး ဝန်ဆောင်မှုကို စတင်ရန် အသုံးလွယ်ရေး ဖြတ်လမ်းလင့်ခ်ကို သုံးပါ"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့သည့်အခါ အသုံးပြုမည့် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ−"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ဝန်ဆောင်မှုများကို ပြောင်းလဲရန် အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့၍ ထိထားပါ။"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ချဲ့ခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 439b0de..28e7d33 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Problem med å registrere Wi-Fi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi-anrop"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-anrop"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-anrop"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-anrop"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Av"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi er foretrukket"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Først-på-mobil"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Ikke gjenkjent"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingeravtrykket er godkjent"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Ansiktet er autentisert"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Ansiktet er autentisert. Trykk på Bekreft"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Maskinvare for fingeravtrykk er ikke tilgjengelig."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingeravtrykket kan ikke lagres. Fjern et eksisterende fingeravtrykk."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsavbrudd for fingeravtrykk er nådd. Prøv på nytt."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Tidsavbrudd for ansikt er nådd. Prøv igjen."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Ansiktet kan ikke lagres."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansikt-operasjonen ble avbrutt."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Ansiktsautentiseringen ble avbrutt av brukeren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"For mange forsøk. Prøv igjen senere."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"For mange forsøk. Ansiktsautentisering er slått av."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Prøv igjen."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Fargekorrigering"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Snarveien for tilgjengelighet slo på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Snarveien for tilgjengelighet slo av <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Bruk tilgjengelighetssnarveien igjen for å starte den nåværende tilgjengelighetsfunksjonen"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Velg en funksjon du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"For å endre funksjoner, trykk på og hold inne Tilgjengelighet-knappen."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Forstørring"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index d45e28b..875f87d 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"तपाईंको सेवा प्रदायकमार्फत Wi-Fi कलिङ सुविधा दर्ता गर्ने क्रममा देखिएको समस्या: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi कलिङ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi कलिङ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कल"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कल"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wifi कलिङ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"निष्क्रिय"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi मनपराइयो"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"रूचाइएको मोबाइल"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"औँठाछाप हार्डवेयर उपलब्ध छैन।"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"औँठाछाप भण्डारण गर्न सकिँदैन। कृपया अवस्थित औठाछाप हटाउनुहोस्।"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"औँठाछापको समय सकिएको छ। फेरि प्रयास गर्नुहोस्।"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"अनुहारको समय सकिएको छ। फेरि प्रयास गर्नुहोस्‌।"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"अनुहार भण्डारण गर्न सकिँदैन।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"अनुहार पहिचान रद्द गरियो।"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"प्रयोगकर्ताले अनुहार प्रमाणीकरण रद्द गर्नु भयो।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"धेरैपटक प्रयासहरू भए। पछि फेरि प्रयास गर्नुहोस्‌।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"अत्यधिक धेरैपटक गलत प्रयासहरू भए। अनुहार प्रमाणिकरणलाई असक्षम पारियो।"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"फेरि प्रयास गर्नुहोस्।"</string>
@@ -1622,6 +1629,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"रङ सच्याउने सुविधा"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"पहुँचको सर्टकटले <xliff:g id="SERVICE_NAME">%1$s</xliff:g> लाई सक्रिय पार्‍यो"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"पहुँचको सर्टकटले <xliff:g id="SERVICE_NAME">%1$s</xliff:g> लाई निष्क्रिय पार्‍यो"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"हालको पहुँचसम्बन्धी सुविधा प्रयोग गर्न फेरि पहुँचसम्बन्धी सर्टकट प्रयोग गर्नुहोस्"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"तपाईंले पहुँच सम्बन्धी बटनलाई ट्याप गर्दा प्रयोग गर्नुपर्ने सुविधा रोज्नुहोस्:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाहरूलाई बदल्न, पहुँच सम्बन्धी बटनलाई छोएर थिची राख्नुहोस्।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"म्याग्निफिकेसन"</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-nl/strings.xml b/core/res/res/values-nl/strings.xml
index df152b2..b95ba19 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -79,7 +79,7 @@
     <string name="CLIRPermanent" msgid="3377371145926835671">"U kunt de instelling voor de beller-ID niet wijzigen."</string>
     <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"Geen service voor mobiele data"</string>
     <string name="RestrictedOnEmergencyTitle" msgid="6855466023161191166">"Noodoproepen niet beschikbaar"</string>
-    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Geen service voor spraakoproepen"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Geen belservice"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"Geen spraakservice of noodoproepen"</string>
     <string name="RestrictedStateContent" msgid="6538703255570997248">"Tijdelijk uitgeschakeld door je provider"</string>
     <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Tijdelijk uitgeschakeld door je provider voor sim <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Probleem bij registratie van Bellen via wifi bij je provider: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Bellen via wifi van %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Bellen via wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Bellen via WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Bellen via WLAN van <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Bellen via wifi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi van <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Uit"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Voorkeur voor wifi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Voorkeur voor mobiel"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Niet herkend"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Vingerafdruk geverifieerd"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Gezicht geverifieerd"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Gezicht geverifieerd. Druk op Bevestigen."</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware voor vingerafdruk niet beschikbaar."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Vingerafdruk kan niet worden opgeslagen. Verwijder een bestaande vingerafdruk."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Time-out bereikt voor vingerafdruk. Probeer het opnieuw."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Time-out voor gezicht bereikt. Probeer opnieuw."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Gezicht kan niet worden opgeslagen."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Bewerking voor gezichtsherkenning geannuleerd."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Gezichtsverificatie geannuleerd door gebruiker."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Te veel pogingen. Probeer het later opnieuw."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Te veel pogingen. Gezichtsherkenning inactief."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Probeer het opnieuw."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Kleurcorrectie"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ingeschakeld"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Gebruik de snelkoppeling voor toegankelijkheid nogmaals om de huidige toegankelijkheidsfunctie te starten"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Kies een functie om te gebruiken wanneer je op de knop Toegankelijkheid tikt:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Als je functies wilt wijzigen, tik je op de knop Toegankelijkheid en houd je deze vast."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergroting"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 78566da..9d3fa8e 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"ଆପଣଙ୍କ କେରିଅର୍ ସହିତ ୱାଇ-ଫାଇ କଲ୍ କରିବା ପାଇଁ ପଞ୍ଜୀକରଣ କରିବାରେ ସମସ୍ୟା: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ୱାଇ-ଫାଇ କଲିଙ୍ଗ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ କଲିଂ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN କଲ୍‍"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN କଲ୍‍"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ୱାଇଫାଇ କଲିଂ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ଅଫ୍"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ପସନ୍ଦ କରାଯାଇଥିବା ୱାଇ-ଫାଇ"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ପସନ୍ଦର ମୋବାଇଲ୍‌"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ହାର୍ଡୱେର୍‍ ଉପଲବ୍ଧ ନାହିଁ।"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ଷ୍ଟୋର୍‍ କରାଯାଇପାରିବ ନାହିଁ। ଦୟାକରି ପୂର୍ବରୁ ଥିବା ଆଙ୍ଗୁଠି ଚିହ୍ନକୁ ବାହାର କରିଦିଅନ୍ତୁ।"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ଆଙ୍ଗୁଠି ଚିହ୍ନର ସମୟ ଶେଷ ହେଲା । ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ଫେସ୍‍ର ସମୟସୀମା ସରିଗଲା। ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ଫେସ୍‍ ମେମୋରୀରେ ଷ୍ଟୋର୍‍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ଫେସ୍‍ର ଅପରେଶନ୍‍ କ୍ୟାନ୍ସଲ୍‍ ହୋ‍ଇଗଲା"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ଉପଯୋଗକର୍ତ୍ତା ମୁହଁ ଚିହ୍ନଟକରଣ ବାତିଲ୍‌ କରିଛନ୍ତି।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ବାରମ୍ବାର ଚେଷ୍ଟା। ପରେ ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ବାରମ୍ବାର ଚେଷ୍ଟା। ଫେସ୍‍ ପ୍ରମାଣୀକରଣ ଅକ୍ଷମ କରାଗଲା।"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ଆକ୍ସେସିବିଲିଟୀ ଶର୍ଟକଟ୍‍ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଅନ୍‍ କରାଯାଇଛି"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ଆକ୍ସେସିବିଲିଟୀ ଶର୍ଟକଟ୍‍ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଅଫ୍‍ କରାଯାଇଛି"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ବର୍ତ୍ତମାନର ଆକ୍ସେସିବିଲିଟୀ ବୈଶିଷ୍ଟ୍ୟ ଆରମ୍ଭ କରିବାକୁ ପୁଣି ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟ୍‍କର୍ଟ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ଆପଣ ଆକ୍ସେସବିଲିଟି ବଟନ୍‍ ଟାପ୍‍ କରିବା ବେଳେ ଏକ ବୈଶିଷ୍ଟ୍ୟ ବ୍ୟବହାର କରିବାକୁ ବାଛନ୍ତୁ:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ବୈଶିଷ୍ଟ୍ୟ ବଦଳାଇବାକୁ, ଆକ୍ସେସବିଲିଟି ବଟନ୍‍ ସ୍ପର୍ଶ କରନ୍ତୁ ଓ ଧରିରଖନ୍ତୁ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ମ୍ୟାଗ୍ନିଫିକେସନ୍‍"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index bb38c88..6e615a8 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਨਾਲ ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ ਨੂੰ ਰਜਿਸਟਰ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ਕਾਲ"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ਕਾਲ"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ਬੰਦ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ਤਰਜੀਹੀ ਵਾਈ-ਫਾਈ"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ਮੋਬਾਈਲ ਨੂੰ ਤਰਜੀਹ ਹੈ"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ।"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਸਕਦਾ। ਕਿਰਪਾ ਕਰਕੇ ਇੱਕ ਮੌਜੂਦਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਟਾਓ।"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋ ਗਿਆ ਹੈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ਚਿਹਰਾ ਪਛਾਣਨ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ਚਿਹਰੇ ਦੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ਚਿਹਰਾ ਪਛਾਣਨ ਦੀ ਪ੍ਰਕਿਰਿਆ ਰੱਦ ਕੀਤੀ ਗਈ।"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ ਨੂੰ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ਹੱਦੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ਹੱਦੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ। ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਰਨ ਬੰਦ ਹੈ।"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"ਰੰਗ ਸੁਧਾਈ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ਮੌਜੂਦਾ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ \'ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ\' ਦੀ ਦੁਬਾਰਾ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਬਦਲਣ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d59b138..81a869a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Podczas rejestrowania połączeń przez Wi-Fi u operatora wystąpił problem: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Połączenia przez Wi-Fi (%s)"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>, połączenia przez Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Połączenie przez WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>, połączenie przez WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>, Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Połączenia przez Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>, VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Wył."</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferuj Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferowane komórkowe"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nie rozpoznano"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Uwierzytelniono odciskiem palca"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Twarz rozpoznana"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Twarz rozpoznana, kliknij Potwierdź"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Czytnik linii papilarnych nie jest dostępny."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Nie można zapisać odcisku palca. Usuń istniejący odcisk palca."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Osiągnięto limit czasu odczytu linii papilarnych. Spróbuj ponownie."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Upłynął limit czasu analizy twarzy. Spróbuj ponownie."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Nie można zapisać informacji o twarzy."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Analiza twarzy została anulowana."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Użytkownik anulował uwierzytelnianie twarzą."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Zbyt wiele prób. Spróbuj ponownie później."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Zbyt wiele prób. Wyłączono uwierzytelnianie za pomocą twarzy."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Spróbuj ponownie."</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korekcja kolorów"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Użyj ponownie skrótu ułatwień dostępu, by uruchomić bieżące ułatwienie dostępu"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Wybierz funkcję używaną po kliknięciu przycisku ułatwień dostępu."</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Aby zmienić funkcje, kliknij i przytrzymaj przycisk ułatwień dostępu."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Powiększenie"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 48302a0..5ac7c2e 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Ocorreu um problema ao registrar a chamada no Wi‑Fi junto à sua operadora: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s chamada Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamada no Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Não reconhecido"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impressão digital autenticada"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Rosto autenticado"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Rosto autenticado, pressione \"Confirmar\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware de impressão digital não disponível."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Não foi possível armazenar a impressão digital. Remova uma impressão digital já existente."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Tempo máx. p/ captura facial atingido. Tente novamente."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Não é possível armazenar um rosto."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação facial cancelada."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticação facial cancelada pelo usuário."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Excesso de tentativas. Tente novamente mais tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Excesso de tentativas. Autenticação facial desat."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Tente novamente."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correção de cor"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atalho de acessibilidade ativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Use o atalho de acessibilidade novamente para iniciar o recurso de acessibilidade atual"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha um recurso a ser usado ao tocar no botão Acessibilidade:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar os recursos, mantenha o botão Acessibilidade pressionado."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3f02828..52f067f 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Ocorreu um problema ao registar a funcionalidade Chamadas Wi-Fi junto do seu operador: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Chamadas por Wi-Fi da %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamadas Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamadas Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Rede Wi-Fi preferida"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
@@ -419,11 +423,11 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas definições de áudio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que a aplicação modifique definições de áudio globais, tais como o volume e qual o altifalante utilizado para a saída de som."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"gravar áudio"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Esta aplicação pode gravar áudio através do microfone a qualquer momento."</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Esta aplicação pode gravar áudio através do microfone em qualquer altura."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"enviar comandos para o SIM"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite que a aplicação envie comandos para o SIM. Esta ação é muito perigosa."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"tirar fotos e vídeos"</string>
-    <string name="permdesc_camera" msgid="5392231870049240670">"Esta aplicação pode tirar fotos e gravar vídeos através da câmara a qualquer momento."</string>
+    <string name="permdesc_camera" msgid="5392231870049240670">"Esta aplicação pode tirar fotos e gravar vídeos através da câmara em qualquer altura."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"controlar vibração"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Permite à aplicação controlar o vibrador."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"marcar números de telefone diretamente"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Não reconhecido."</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"A impressão digital foi autenticada."</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Rosto autenticado."</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Rosto autenticado. Prima Confirmar."</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware de impressão digital não disponível."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Não é possível armazenar a impressão digital. Remova uma impressão digital existente."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Foi atingido o limite de tempo da impressão digital. Tente novamente."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Limite de tempo de rosto atingido. Tente novamente."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Não é possível armazenar o rosto."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação de rosto cancelada."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticação facial cancelada pelo utilizador."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiadas tentativas. Tente novamente mais tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiadas tentativas. Autenticação facial desativada."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Tente novamente."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correção da cor"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O Atalho de acessibilidade ativou o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O Atalho de acessibilidade desativou o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Utilize novamente o atalho de acessibilidade para iniciar a funcionalidade de acessibilidade atual."</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha uma funcionalidade para utilizar quando tocar no botão Acessibilidade:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar as funcionalidades, toque sem soltar no botão Acessibilidade."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 48302a0..5ac7c2e 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Ocorreu um problema ao registrar a chamada no Wi‑Fi junto à sua operadora: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s chamada Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamada no Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Não reconhecido"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impressão digital autenticada"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Rosto autenticado"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Rosto autenticado, pressione \"Confirmar\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware de impressão digital não disponível."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Não foi possível armazenar a impressão digital. Remova uma impressão digital já existente."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Tempo máx. p/ captura facial atingido. Tente novamente."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Não é possível armazenar um rosto."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação facial cancelada."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticação facial cancelada pelo usuário."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Excesso de tentativas. Tente novamente mais tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Excesso de tentativas. Autenticação facial desat."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Tente novamente."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Correção de cor"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atalho de acessibilidade ativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Use o atalho de acessibilidade novamente para iniciar o recurso de acessibilidade atual"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha um recurso a ser usado ao tocar no botão Acessibilidade:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar os recursos, mantenha o botão Acessibilidade pressionado."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 1c95559..0c945f7 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -129,10 +129,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"A apărut o problemă la înregistrarea apelării prin Wi‑Fi la operatorul dvs.: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Apelare prin Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Apelare prin Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Apel WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Apel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Apelare prin Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Dezactivată"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Se preferă conexiunea Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Se preferă datele mobile"</string>
@@ -527,6 +531,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nu este recunoscut"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Amprentă autentificată"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Chip autentificat"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Chip autentificat, apăsați Confirmați"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware-ul pentru amprentă nu este disponibil."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Amprenta nu poate fi stocată. Eliminați o amprentă existentă."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timpul pentru amprentare a expirat. Încercați din nou."</string>
@@ -563,6 +569,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Timpul pentru reunoaștere facială a expirat. Încercați din nou."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Chipul nu poate fi stocat."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operațiunea privind chipul a fost anulată."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentificarea chipului anulată de utilizator."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Prea multe încercări. Reîncercați mai târziu."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Prea multe încercări. Autentificarea facială este dezactivată."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Încercați din nou."</string>
@@ -1640,6 +1647,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Corecția culorii"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Comanda rapidă de accesibilitate a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Comanda rapidă de accesibilitate a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Folosiți din nou comanda rapidă Accesibilitate pentru a porni funcția de accesibilitate prezentă"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Alegeți o funcție pe care să o folosiți când atingeți butonul Accesibilitate:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pentru a schimba funcțiile, atingeți lung butonul Accesibilitate."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Mărire"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c14bce4..fd70e9c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Ошибка подключения функции \"Звонки по Wi-Fi\" через вашего оператора: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Звонки по Wi-Fi (%s)"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Звонки по Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Вызов WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> Вызов WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Звонки по Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Отключено"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Приоритет Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Приоритет мобильного Интернета"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Сканер недоступен"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Чтобы сохранить новый отпечаток, удалите существующий."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Превышено время ожидания. Повторите попытку."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Превышено время ожидания. Повторите попытку."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Невозможно сохранить распознанное лицо"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Распознавание отменено"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Распознавание лица отменено пользователем."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Слишком много попыток. Повторите позже."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Слишком много попыток. Сканер отключен."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Попробуйте ещё раз"</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Коррекция цвета"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> включен"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> отключен"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Чтобы активировать выбранные специальные возможности, воспользуйтесь быстрым включением ещё раз"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберите функцию, которая запускается при нажатии кнопки специальных возможностей:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Чтобы изменить функцию, удерживайте кнопку специальных возможностей."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Увеличение"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 0f353f2..3bd8ceb 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"ඔබගේ වාහකය සමඟ Wi-Fi ඇමතුම් ලියාපදිංචි කිරීම නිකුත් කරන්න: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi අමතමින්"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi ඇමතුම්"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ඇමතුම"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ඇමතුම්"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi ඇමතුම් | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ක්‍රියාවිරහිතයි"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi වඩා කැමතියි"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ජංගම කැමතියි"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ඇඟිලි සලකුණු දෘඪාංගය ලද නොහැකිය."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ඇඟිලි සලකුණ ගබඩා කළ නොහැක. දැනට පවතින ඇඟිලි සලකුණක් ඉවත් කරන්න."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ඇඟිලි සලකුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"මුහුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"මුහුණ ගබඩා කළ නොහැක."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"මුහුණු මෙහෙයුම අවලංගු කරන ලදී."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"පරිශීලකයා විසින් මුහුණ සත්‍යාපනය අවලංගු කරන ලදී."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"උත්සාහයන් ඉතා වැඩි ගණනකි. පසුව නැවත උත්සාහ කරන්න."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"උත්සාහයන් ඉතා වැඩි ගණනකි. මුහුණු සත්‍යාපනය අබල කරන ලදී."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"නැවත උත්සාහ කරන්න."</string>
@@ -1618,6 +1625,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"වර්ණ නිවැරදි කිරීම"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ප්‍රවේශ්‍යතා කෙටි මග <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාත්මක කරන ලදී"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ප්‍රවේශ්‍යතා කෙටි මග <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාවිරහිත කරන ලදී"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"වර්තමාන ප්‍රවේශ්‍යතා විශේෂංගය ආරම්භ කිරීම සඳහා ප්‍රවේශ්‍යතා කෙටි මග භාවිතා කරන්න"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කරන විට භාවිතා කිරීමට අංගයක් තෝරාගන්න:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"අංග වෙනස් කිරීමට ප්‍රවේශ්‍යතා බොත්තම ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"විශාලනය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 3109702..c0981ce 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Pri registrácii volania cez Wi‑Fi u operátora nastala chyba <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Volanie siete Wi‑Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> volanie cez Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Volanie cez WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> volanie cez WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Volanie cez WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuté"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferovať Wi‑Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferovať mobilné spojenie"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nerozpoznané"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Odtlačok bol overený"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Tvár bola overená"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Tvár bola overená, stlačte tlačidlo potvrdenia"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardvér na snímanie odtlačku prsta nie je k dispozícii"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Odtlačok prsta nie je možné uložiť. Odstráňte existujúci odtlačok."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Časový limit rozpoznania odtlačku vypršal. Skúste to znova."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Limit rozpoznania tváre vypršal. Skúste to znova."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Tvár sa nedá uchovať."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operácia týkajúca sa tváre bola zrušená"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Overenie tváre bolo zrušené používateľom."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Príliš veľa pokusov. Skúste to znova neskôr."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Príliš veľa pokusov. Overenie tváre je zakázané."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Skúste to znova."</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Úprava farieb"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skratka dostupnosti zapla službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skratka dostupnosti vypla službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Znova použite skratku dostupnosti, čím sprístupníte aktuálnu funkciu dostupnosti"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ak chcete zmeniť funkcie, klepnite na tlačidlo dostupnosti a podržte ho"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Priblíženie"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 4575d00..261e6ed 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Težava pri registriranju klicanja prek Wi-Fi-ja pri operaterju: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Klicanje prek Wi-Fi-ja (%s)"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Klicanje prek Wi-Fi-ja operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Klic prek omrežja WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Klic prek omrežja WLAN operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Klicanje prek WiFi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"Govor prek Wi-Fi-ja operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Izklopljeno"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednostno Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Prednostno mobilno"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Ni prepoznano"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Pristnost prstnega odtisa je preverjena"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Pristnost obraza je potrjena"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Pristnost obraza je preverjena. Pritisnite gumb »Potrdi«."</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Strojna oprema za prstne odtise ni na voljo."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Prstnega odtisa ni mogoče shraniti. Odstranite obstoječi prstni odtis."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Dosežena časovna omejitev za prstni odtis. Poskusite znova."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Dosežena časovna omejitev za obraz. Poskusite znova."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Obraza ni mogoče shraniti."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Dejanje z obrazom je bilo preklicano."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Preverjanje pristnosti obraza preklical uporabnik"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Preveč poskusov. Poskusite znova pozneje."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Preveč poskusov. Preverjanje pristnosti obraza je onemogočeno."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Poskusite znova."</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Popravljanje barv"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Bližnjica funkcij za ljudi s posebnimi potrebami je vklopila <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Bližnjica funkcij za ljudi s posebnimi potrebami je izklopila <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Če želite zagnati trenutno funkcijo za ljudi s posebnimi potrebami, znova uporabite bližnjico funkcij za ljudi s posebnimi potrebami"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izberite funkcijo, ki jo želite uporabljati, ko se dotaknete gumba »Dostopnost«:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Če želite spremeniti funkcije, se dotaknite gumba »Dostopnost« in ga pridržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Povečava"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1149421..4b6cb09 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Problem gjatë regjistrimit të telefonatave me Wi‑Fi me operatorin tënd celular: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Telefonatat me Wi-Fi nga %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Telefonatë me Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Telefonatë me WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Telefonatë me WLAN në <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Telefonatë me Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi në <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Çaktivizuar"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferohet Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferohet rrjeti celular"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Nuk njihet"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Gjurma e gishtit u vërtetua"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Fytyra u vërtetua"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Fytyra u vërtetua, shtyp \"Konfirmo\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardueri i gjurmës së gishtit nuk mundësohet."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Gjurma e gishtit nuk mund të ruhet. Hiq një gjurmë gishti ekzistuese."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Koha e veprimit për gjurmën e gishtit skadoi. Provo përsëri."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Mbaroi afati për fytyrën. Provo sërish."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Fytyra nuk mund të ruhet."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Veprimi me fytyrën u anulua."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Vërtetimi me fytyrë u anulua nga përdoruesi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Shumë përpjekje. Provo sërish më vonë."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Shumë përpjekje. Vërtetimi për fytyrën joaktiv."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Provo sërish."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korrigjimi i ngjyrës"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Shkurtorja e qasshmërisë e aktivizoi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Shkurtorja e qasshmërisë e çaktivizoi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Përdor përsëri \"Shkurtoren e qasshmërisë\" për të nisur funksionin aktual të qasshmërisë"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Zgjidh një funksion për ta përdorur kur troket butonin e \"Qasshmërisë\":"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Për të ndryshuar funksionet, prek dhe mbaj butonin e \"Qasshmërisë\"."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zmadhimi"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7536531..449fdfc 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -129,10 +129,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Проблем у вези са регистровањем позивања преко Wi‑Fi-ја код мобилног оператера: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Wi-Fi позивање преко оператера %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> позивање преко Wi-Fi-ја"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN позив"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Позивање преко Wi-Fi-ја | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Искључено"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Предност има Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Желим мобилне податке"</string>
@@ -527,6 +531,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Хардвер за отиске прстију није доступан."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Није могуће сачувати отисак прста. Уклоните неки од постојећих отисака прстију."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Временско ограничење за отисак прста је истекло. Пробајте поново."</string>
@@ -563,6 +569,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Истекло је време за проверу лица. Пробајте поново."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Није могуће сачувати лице."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Обрада лица је отказана."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Корисник је отказао потврду лица."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Превише покушаја. Пробајте поново касније."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Више покушаја. Потврда идентитета је онемогућена."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Пробајте поново."</string>
@@ -1640,6 +1647,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Корекција боја"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Пречица за приступачност је укључила услугу <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Пречица за приступачност је искључила услугу <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Употребите поново пречицу за приступачност да бисте покренули актуелну функцију приступачности"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изаберите функцију која ће се користити када додирнете дугме за приступачност:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Притисните и задржите дугме за приступачност да бисте мењали функције."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Увећање"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 31bb349..9f46514 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Följande fel uppstod när Wi-Fi-samtal skulle registreras hos operatören: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi-samtal"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-samtal via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-samtal"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-samtal via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-samtal | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi via <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Av"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi i första hand"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Använd mobildata"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Identifierades inte"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingeravtrycket har autentiserats"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Ansiktet har autentiserats"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Ansiktet har autentiserats. Tryck på Bekräfta"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Det finns ingen maskinvara för fingeravtryck."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingeravtrycket kan inte lagras. Ta bort ett befintligt fingeravtryck."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsgränsen för fingeravtrycket har uppnåtts. Försök igen."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Tidsgränsen för ansikte har nåtts. Försök igen."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Det gick inte att lagra ansiktet."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansiktsåtgärden har avbrutits."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentiseringen av ansiktet avbröts av användaren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Du har gjort för många försök. Försök igen senare."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"För många försök. Ansiktsautentisering inaktiverad"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Försök igen."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Färgkorrigering"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiverades av Aktivera tillgänglighet snabbt"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> inaktiverades av Aktivera tillgänglighet snabbt"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Använd Aktivera tillgänglighet snabbt en gång till om du vill aktivera tillgänglighetsfunktionen i fråga"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Välj en funktion som ska användas när du trycker på tillgänglighetsknappen:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Tryck länge på tillgänglighetsknappen för att ändra funktioner."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Förstoring"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3d26224..b0858dc 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -128,8 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Tatizo limetokea wakati wa kuisajili huduma ya kupiga simu kupitia Wi‑Fi kwa mtoa huduma wako: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for wfcSpnFormats:0 (6830082633573257149) -->
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Kupiga Simu Kupitia Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Simu ya WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Simu ya WLAN ya <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Kupiga Simu kupitia WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi ya <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Imezimwa"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi inapedelewa"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mtandao wa simu unapendelewa"</string>
@@ -522,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Hayatambuliki"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Imethibitisha alama ya kidole"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Uso umethibitishwa"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Uso umethibitishwa, tafadhali bonyeza thibitisha"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Maunzi ya kitambulisho hayapatikani."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Kitambulisho hakiwezi kuhifadhiwa. Tafadhali ondoa kitambulisho kilichopo."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Muda wa kitambulisho umekwisha. Jaribu tena."</string>
@@ -558,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Muda wa kutambua uso umeisha. Jaribu tena."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Huwezi kuhifadhi uso."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Utendaji wa kitambulisho umeghairiwa."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Uthibitishaji wa uso umeghairiwa na mtumiaji."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Umejaribu mara nyingi mno. Jaribu tena baadaye."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Umejaribu mara nyingi mno. Kitambuzi cha uso kimezimwa."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Jaribu tena."</string>
@@ -1614,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Usahihishaji wa rangi"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Njia ya mkato ya zana za walio na matatizo ya kuona au kusikia imewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Njia ya mkato ya zana za walio na matatizo ya kuona au kusikia imezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Tumia njia ya Mkato wa Zana za walio na matatizo ya kuona au kusikia tena ili kuanzisha kipengele kilichopo cha walio na matatizo ya kuona au kusikia"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Chagua kipengele utakachotumia, ukigonga Kitufe cha zana za walio na matatizo ya kuona au kusikia."</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ili kubadilisha vipengele, gusa na ushikile Kitufe cha zana za walio na matatizo ya kuona au kusikia."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ukuzaji"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 35592a6..3bf8b78 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"உங்கள் மொபைல் நிறுவனத்துடன் வைஃபை அழைப்பைப் பதிவுசெய்வதில் சிக்கல்: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s வைஃபை அழைப்பு"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> வைஃபை அழைப்பு"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN அழைப்பு"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN அழைப்பு"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> வைஃபை"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"வைஃபை அழைப்பு | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ஆஃப்"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"வைஃபைக்கு முன்னுரிமை"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"மொபைல் தரவிற்கு முன்னுரிமை"</string>
@@ -514,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>
@@ -523,9 +526,10 @@
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"கைரேகை வன்பொருள் இல்லை."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"கைரேகையைச் சேமிக்க முடியவில்லை. ஏற்கனவே உள்ள கைரேகையை அகற்றவும்."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"கைரேகைக்கான நேரம் முடிந்தது. மீண்டும் முயலவும்."</string>
@@ -562,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"முகப் பதிவிற்கான நேரம் முடிந்தது. மீண்டும் முயல்க."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"முகத்தைச் சேமிக்க இயலாது."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"முக அங்கீகாரச் செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"பயனர், முக அங்கீகாரத்தை ரத்துசெய்தார்."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"பலமுறை முயன்றுவிட்டீர்கள். பிறகு முயலவும்."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"பலமுறை தோல்வி. முக அங்கீகாரம் முடக்கப்பட்டது."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"மீண்டும் முயலவும்."</string>
@@ -1619,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"வண்ணத் திருத்தம்"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"அணுகல்தன்மைக் குறுக்குவழியானது <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐ இயக்கியது"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"அணுகல்தன்மைக் குறுக்குவழியானது <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐ முடக்கியது"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"தற்போதுள்ள அணுகல்தன்மை அம்சத்தை மீண்டும் தொடங்க ’அணுகல்தன்மை ஷார்ட்கட்டைப்’ பயன்படுத்தவும்"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"அணுகல்தன்மைப் பொத்தானைத் தட்டி, பயன்படுத்துவதற்கான அம்சத்தைத் தேர்ந்தெடுக்கவும்:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"அம்சங்களை மாற்ற, அணுகல்தன்மைப் பொத்தானைத் தொட்டுப் பிடித்திருக்கவும்."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"பெரிதாக்கல்"</string>
@@ -1753,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-te/strings.xml b/core/res/res/values-te/strings.xml
index 2027d33..a5430b6 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"మీ క్యారియర్‌తో Wi‑Fi కాలింగ్‌ని నమోదు చేయడంలో సమస్య: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi కాలింగ్"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi కాలింగ్"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN కాల్"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN కాల్"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi కాలింగ్ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ఆఫ్‌లో ఉంది"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fiకి ప్రాధాన్యత"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"మొబైల్‌కి ప్రాధాన్యత ఇవ్వబడింది"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"వేలిముద్ర హార్డ్‌వేర్ అందుబాటులో లేదు."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"వేలిముద్రను నిల్వ చేయడం సాధ్యపడదు. దయచేసి ఇప్పటికే ఉన్న వేలిముద్రను తీసివేయండి."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"వేలిముద్ర గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"ముఖ గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"ముఖం నిల్వ చేయబడదు."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ముఖ కార్యకలాపం రద్దయింది."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"వినియోగదారు ద్వారా ముఖ ప్రమాణీకరణ రద్దు చేయబడింది."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. ముఖ ప్రమాణీకరణ నిలిపివేయబడింది."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"మళ్లీ ప్రయత్నించండి."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"రంగు సవరణ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ప్రస్తుత యాక్సెస్ సౌలభ్య ఫీచర్‌ను ఉపయోగించడానికి యాక్సెసిబిలిటీ షార్ట్‌కట్‌ను మళ్లీ ప్రారంభించండి"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"యాక్సెస్ సామర్థ్య బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ఫీచర్లను మార్చడానికి, యాక్సెస్ సామర్థ్య బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"మాగ్నిఫికేషన్"</string>
diff --git a/core/res/res/values-television/themes.xml b/core/res/res/values-television/themes.xml
index 0712cbc..48b59c7 100644
--- a/core/res/res/values-television/themes.xml
+++ b/core/res/res/values-television/themes.xml
@@ -15,7 +15,6 @@
 -->
 <resources>
     <style name="Theme.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
-    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
     <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-television/themes_device_defaults.xml b/core/res/res/values-television/themes_device_defaults.xml
index 293591a..fdd0624 100644
--- a/core/res/res/values-television/themes_device_defaults.xml
+++ b/core/res/res/values-television/themes_device_defaults.xml
@@ -15,8 +15,20 @@
 -->
 <resources>
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
-    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material.Autofill" />
-    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Autofill.Save" />
+
+    <!-- TODO(b/116457731): remove colorBackground from colors_material.xml if not used anymore -->
+    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material">
+        <item name="colorBackground">@color/autofill_background_material_dark</item>
+    </style>
+    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Panel">
+        <item name="colorBackground">@color/autofill_background_material_dark</item>
+    </style>
+
+    <!-- TV always use dark mode -->
+    <style name="Theme.DeviceDefault.Autofill.Light" parent="Theme.DeviceDefault.Autofill"/>
+    <style name="Theme.DeviceDefault.Light.Autofill.Save" parent="Theme.DeviceDefault.Autofill.Save"/>
+
     <style name="Theme.DeviceDefault.Resolver" parent="Theme.Leanback.Resolver" />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 84fd018..0b7e031 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"เกิดปัญหาในการลงทะเบียนการโทรผ่าน Wi‑Fi กับผู้ให้บริการของคุณ: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"กำลังเรียก Wi-Fi ของ %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"การโทรผ่าน Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"การโทรผ่าน WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"การโทรผ่าน WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"การโทรผ่าน Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ปิด"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ต้องการใช้ Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ต้องการใช้อินเทอร์เน็ตมือถือ"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ฮาร์ดแวร์ลายนิ้วมือไม่พร้อมใช้งาน"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ไม่สามารถเก็บลายนิ้วมือได้ โปรดนำลายนิ้วมือที่มีอยู่ออก"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"หมดเวลาใช้ลายนิ้วมือแล้ว โปรดลองอีกครั้ง"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"หมดเวลาใช้ใบหน้าแล้ว โปรดลองอีกครั้ง"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"จัดเก็บข้อมูลใบหน้าไม่ได้"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ยกเลิกการดำเนินการกับใบหน้าแล้ว"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"ผู้ใช้ยกเลิกการตรวจสอบสิทธิ์ใบหน้า"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ดำเนินการหลายครั้งเกินไป ปิดใช้การตรวจสอบสิทธิ์ด้วยใบหน้าแล้ว"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"ลองอีกครั้ง"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"การปรับแก้สี"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ทางลัดการเข้าถึงเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ทางลัดการเข้าถึงปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"ใช้ทางลัดการช่วยเหลือพิเศษอีกครั้งเพื่อเริ่มฟีเจอร์การช่วยเหลือพิเศษปัจจุบัน"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่ม \"การเข้าถึงพิเศษ\":"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนฟีเจอร์ ให้แตะปุ่ม \"การเข้าถึงพิเศษ\" ค้างไว้"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"การขยาย"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 49318cf..e21f59c 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Nagkaroon ng isyu sa pagrehistro ng pagtawag gamit ang Wi‑Fi sa iyong carrier: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Pagtawag sa Pamamagitan ng Wi-Fi ng %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Pagtawag Gamit ang Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Pagtawag Gamit ang WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Pagtawag Gamit ang WLAN ng <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Pagtawag Gamit ang Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi ng <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Naka-off"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Mas gusto ang Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mas gusto ang mobile"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Hindi nakilala"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Na-authenticate ang fingerprint"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Na-authenticate ang mukha"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Na-authenticate ang mukha, pakipindot ang kumpirmahin"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hindi available ang hardware na ginagamitan ng fingerprint."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Hindi maiimbak ang fingerprint. Mangyaring mag-alis ng umiiral nang fingerprint."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Nag-time out ang fingerprint. Subukang muli."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Nag-time out ang mukha. Subukang muli."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Hindi ma-store ang mukha."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Nakansela ang operation kaugnay ng mukha."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Kinansela ng user ang pag-authenticate ng mukha."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Masyadong maraming pagsubok. Subukang muli mamaya."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Sobrang pagsubok. Bawal na: facial authentication."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Subukang muli."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Pagwawasto ng Kulay"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Na-on ng Shortcut sa Accessibility ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Na-off ng Shortcut sa Accessibility ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Gamiting muli ang Shortcut sa Pagiging Naa-access para simulan ang kasalukuyang feature ng pagiging naa-access"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pumili ng feature na gagamitin kapag na-tap mo ang button ng Pagiging Naa-access:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Upang baguhin ang mga feature, pindutin nang matagal ang button ng Pagiging Naa-access."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pag-magnify"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c6d18ec..912db20 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Kablosuz çağrının operatörünüze kaydı sırasında hata oluştu: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Kablosuz Çağrı"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Kablosuz Çağrı"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Üzerinden Çağrı"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Üzerinden Çağrı"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Kablosuz"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Kablosuz Çağrı | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Kapalı"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Kablosuz bağlantı tercihli"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil tercihli"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Tanınmadı"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Parmak izi kimlik doğrulaması yapıldı"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Yüz kimliği doğrulandı"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Yüz kimliği doğrulandı, lütfen onayla\'ya basın"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Parmak izi donanımı kullanılamıyor."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Parmak izi depolanamıyor. Lütfen mevcut parmak izlerinden birini kaldırın."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Parmak izi için zaman aşımı oluştu. Tekrar deneyin."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Yüz için zaman aşımı oluştu. Tekrar deneyin."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Yüz kaydedilemiyor."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Yüz işlemi iptal edildi."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Yüz kimlik doğrulama işlemini kullanıcı iptal etti."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Çok fazla deneme yapıldı. Yüz kimlik doğrulaması devre dışı bırakıldı."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Tekrar deneyin."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Renk Düzeltme"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Erişilebilirlik Kısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini açtı"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Erişilebilirlik Kısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kapattı"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Geçerli erişilebilirlik özelliğini başlatmak için Erişilebilirlik Kısayolu\'nu tekrar kullanın"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak üzere bir özellik seçin:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Özellikleri değiştirmek için Erişilebilirlik düğmesine dokunup basılı tutun."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Büyütme"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6e6dd9a..f84e3e2 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -130,10 +130,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Проблема з реєстрацією дзвінків через Wi‑Fi у вашого оператора: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Дзвінок через Wi-Fi від оператора %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Виклики <xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Виклик через WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Виклик <xliff:g id="SPN">%s</xliff:g> через WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Виклики через Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> через VoWi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Вимкнено"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi за умовчанням"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Мобільна мережа за умовчанням"</string>
@@ -530,6 +534,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Апаратне забезпечення для сканування відбитка недоступне."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Не вдалося зберегти відбиток. Видаліть наявний відбиток."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час очікування відбитка минув. Повторіть спробу."</string>
@@ -566,6 +572,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Час очікування обличчя минув. Повторіть спробу."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Не вдається зберегти обличчя."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Дію з обличчям скасовано."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Користувач скасував автентифікацію облич."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Забагато спроб. Повторіть пізніше."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Забагато спроб. Автентифікацію обличчя вимкнено."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Повторіть спробу."</string>
@@ -1664,6 +1671,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Корекція кольорів"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Ярлик спеціальних можливостей увімкнув <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Ярлик спеціальних можливостей вимкнув <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Щоб запустити поточну функцію спеціальних можливостей, знову скористайтеся відповідним ярликом"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Виберіть функцію для кнопки спеціальних можливостей:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Щоб змінити функцію, натисніть і втримуйте кнопку спеціальних можливостей."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Збільшення"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 2a2ca62..dc801cd 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"‏آپ کے کیریئر کے ساتھ Wi‑Fi کالنگ رجسٹر کرنے میں مسئلہ درپیش ہے: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"‎%s"</item>
-    <item msgid="4397097370387921767">"‏‎%s Wi-Fi کالنگ"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏<xliff:g id="SPN">%s</xliff:g> Wi-Fi کالنگ"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏WLAN کال"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏<xliff:g id="SPN">%s</xliff:g> WLAN کال"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"‏WiFi کالنگ | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"آف"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏Wi-Fi ترجیحی"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"موبائل ترجیحی"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"فنگر پرنٹ ہارڈ ویئر دستیاب نہیں ہے۔"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"فنگر پرنٹ اسٹور نہیں کیا جا سکتا ہے۔ براہ کرم ایک موجودہ فنگر پرنٹ ہٹائیں۔"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"چہرہ پہچانے کی میعاد ختم ہو گئی۔ دوبارہ کوشش کریں۔"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"چہرے کو اسٹور نہیں کیا جا سکتا۔"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"چہرے پر ہونے والی کارروائی منسوخ ہو گئی۔"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"صارف نے چہرے کی تصدیق کو مسترد کر دیا۔"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"کافی زیادہ کوششیں کی گئیں۔ دوبارہ کوشش کریں۔"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"کافی زیادہ کوششیں کی گئیں۔ چہرے کی توثیق منسوخ ہو گئی۔"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"دوبارہ کوشش کریں۔"</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"رنگ کی تصحیح"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ایکسیسبیلٹی شارٹ کٹ نے <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کر دیا"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ایکسیسبیلٹی شارٹ کٹ نے <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آف کر دیا"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"موجودہ ایکسیسبیلٹی خصوصیت کو شروع کرنے کیلئے دوبارہ ایکسیسبیلٹی شارٹ کٹ استعمال کریں"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک خصوصیت چنیں:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"خصوصیات تبدیل کرنے کیلئے، ایکسیسبیلٹی بٹن ٹچ کریں اور دبائے رکھیں۔"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"میگنیفکیشن"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 7ffc7e7..e51b810 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Aloqa operatoringiz orqali Wi-Fi chaqiruv funksiyasinini ulashda xato: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi qo‘ng‘iroqlar"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi chaqiruv"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN chaqiruv"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN chaqiruv"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi chaqiruv | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"O‘chiq"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi afzalligi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil internet afzalligi"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Aniqlanmadi"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Barmoq izi tekshirildi"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Yuzingiz aniqlandi"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Yuzingiz aniqlandi, tasdiqlash uchun bosing"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Barmoq izi skaneri ish holatida emas."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Barmoq izini saqlab bo‘lmadi. Mavjud barmoq izlaridan birini o‘chirib tashlang."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Yuzni aniqlash vaqti tugadi. Qaytadan urining."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Aniqlangan yuz saqlanmadi."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Yuzni aniqlash bekor qilindi."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Yuz tekshiruvi bekor qilindi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Juda ko‘p urinildi. Keyinroq qaytadan urining."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Juda ko‘p urinildi. Skaner faolsizlantirildi."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Qaytadan urining."</string>
@@ -1617,6 +1624,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Rangni tuzatish"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmati yoqildi"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmati o‘chirib qo‘yildi"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Joriy maxsus imkoniyatlar funksiyasini boshlash uchun tezkor ishga tushirishdan qayta foydalaning"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Maxsus imkoniyatlar tugmasi bosilganda ishga tushadigan funksiyani tanlang:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funksiyalarni o‘zgartirish uchun Maxsus imkoniyatlar tugmasini bosib turing."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Kattalashtirish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a5f458b..4d8a20b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Sự cố khi đăng ký dịch vụ gọi qua Wi‑Fi với nhà mạng của bạn: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"Gọi điện qua Wi-Fi %s"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Gọi qua Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Cuộc gọi qua WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Cuộc gọi qua WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Gọi qua Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Tắt"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Ưu tiên Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Ưu tiên dữ liệu di động"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Không nhận dạng được"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Đã xác thực vân tay"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Đã xác thực khuôn mặt"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Đã xác thực khuôn mặt, vui lòng nhấn để xác nhận"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Phần cứng vân tay không khả dụng."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Không thể lưu vân tay. Vui lòng xóa vân tay hiện có."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Đã hết thời gian chờ vân tay. Hãy thử lại."</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Đã hết thời gian chờ khuôn mặt. Hãy thử lại."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Không thể lưu khuôn mặt."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Đã hủy thao tác dùng khuôn mặt."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Người dùng đã hủy thao tác xác thực khuôn mặt."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Bạn đã thử quá nhiều lần. Hãy thử lại sau."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Đã thử quá nhiều lần. Đã tắt xác thực khuôn mặt."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Hãy thử lại."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Sửa màu"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Đã bật phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Đã tắt phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Sử dụng lại Phím tắt hỗ trợ tiếp cận để bắt đầu tính năng hỗ trợ tiếp cận hiện tại"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Chọn tính năng sẽ sử dụng khi bạn nhấn nút Trợ năng:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Để thay đổi các tính năng, hãy chạm và giữ nút Trợ năng."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Phóng to"</string>
diff --git a/core/res/res/values-watch/themes.xml b/core/res/res/values-watch/themes.xml
deleted file mode 100644
index 1be47ba..0000000
--- a/core/res/res/values-watch/themes.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <!-- Theme for the dialog shown when an app crashes or ANRs. Override to make it dark. -->
-    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
-        <item name="windowContentTransitions">false</item>
-        <item name="windowActivityTransitions">false</item>
-        <item name="windowCloseOnTouchOutside">false</item>
-    </style>
-</resources>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index a7736e7c..bfba312 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -422,6 +422,13 @@
         <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
     </style>
 
+    <!-- Theme for the dialog shown when an app crashes or ANRs. Override to make it dark. -->
+    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
+        <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
+        <item name="windowCloseOnTouchOutside">false</item>
+    </style>
+
     <style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
         <!-- Color palette Dark -->
         <item name="colorPrimary">@color/primary_device_default_dark</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 966a5a5..609f9bcf 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"向您的运营商注册 WLAN 通话时遇到问题:<xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s WLAN 通话功能"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通话"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WLAN 通话 | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"关闭"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"首选 WLAN"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"首选移动数据网络"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"指纹硬件无法使用。"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"无法存储指纹。请移除一个现有的指纹。"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指纹录入操作超时,请重试。"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"面孔处理操作超时,请重试。"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"无法存储面孔。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"面孔处理操作已取消。"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"用户已取消面孔验证。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"尝试次数过多,请稍后重试。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"尝试次数过多,系统已停用人脸身份验证功能。"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"请重试。"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"色彩校正"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"无障碍快捷方式已开启<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"无障碍快捷方式已关闭<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"再次使用无障碍快捷方式即可启动目前设置的无障碍功能"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"选择按下“无障碍”按钮时要使用的功能:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"要更改指定的功能,请触摸并按住“无障碍”按钮。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大功能"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 87eb41f..2e3c7d7 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"向您的流動網絡供應商註冊 Wi-Fi 通話時發生問題:<xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi 通話"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi 通話 | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"關閉"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"首選 Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"流動數據優先"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"無法使用指紋軟件。"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"指紋無法儲存。請移除現有指紋。"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋已逾時。請再試一次。"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"臉孔操作已逾時,請再試一次。"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"無法儲存臉孔。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔操作已取消。"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"使用者已取消臉孔驗證。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"嘗試次數過多,臉孔驗證已停用。"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"請再試一次。"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"色彩校正"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"無障礙功能快速鍵已啟用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"無障礙功能快速鍵已停用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"再用一次無障礙功能捷徑,就可以啟用宜家設定咗嘅無障礙功能"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"請選擇輕按「無障礙功能」按鈕時使用的功能:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"如要變更功能,可按住「無障礙功能」按鈕。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index bd36ed6..9149f47 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"向你的電信業者註冊 Wi‑Fi 通話時發生問題:<xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s Wi-Fi 通話"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi 通話 | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"關閉"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi 優先"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"行動網路優先"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <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>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"指紋硬體無法使用。"</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"無法儲存指紋,請先移除現有指紋。"</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋處理作業逾時,請再試一次。"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"臉孔處理作業逾時,請再試一次。"</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"無法儲存臉孔。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔處理作業已取消。"</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"使用者已取消臉孔驗證。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"嘗試次數過多,臉孔驗證功能已停用。"</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"請再試一次。"</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"色彩校正"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"協助工具捷徑啟用了「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"協助工具捷徑停用了「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"再次使用協助工具捷徑即可啟動目前設定的無障礙功能"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"輕觸 [協助工具] 按鈕後,選擇你想使用的功能:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"如要變更指派的功能,請按住 [協助工具] 按鈕。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index fd6614c..75709ca 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -128,10 +128,14 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7372514042696663278">"Inkinga yokubhalisa ukushaya kwe-Wi-Fi ngenkampani yakho yenethiwekhi: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
-  <string-array name="wfcSpnFormats">
-    <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ukushaya kwe-Wi-Fi"</item>
-  </string-array>
+    <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
+    <skip />
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ukushaya kwe-Wi-Fi"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Ikholi ye-WLAN"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> ikholi ye-WLAN"</string>
+    <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Ukushaya kwe-WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Valiwe"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Kuncanyelwa i-Wi-Fi"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Kuncanyelwa iselula"</string>
@@ -524,6 +528,8 @@
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Akwaziwa"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Isingxivizo somunwe sigunyaziwe"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Ubuso bufakazelwe ubuqiniso"</string>
+    <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Ukuqinisekiswa kobuso, sicela ucindezele okuthi qinisekisa"</string>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Izingxenyekazi zekhompuyutha zezingxivizo zeminwe azitholakali."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Izigxivizo zeminwe azikwazi ukugcinwa. Sicela ususe izigxivizo zeminwe ezikhona."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Kufinyelelwe isikhathi sokuvala sezigxivizo zeminwe. Zama futhi"</string>
@@ -560,6 +566,7 @@
     <string name="face_error_timeout" msgid="4014326147867150054">"Kufinyelelwe kusikhathi sokuvala sobuso. Zama futhi."</string>
     <string name="face_error_no_space" msgid="8224993703466381314">"Ubuso abukwazi ukugcinwa."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Umsebenzi wobuso ukhanselwe."</string>
+    <string name="face_error_user_canceled" msgid="8943921120862164539">"Ukufakazela ubuqiniso kobuso kukhanselwe umsebenzisi"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Imizamo eminingi kakhulu. Zama futhi emuva kwesikhathi."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Imizamo eminingi kakhulu. Ukufakazela ubuqiniso kobuso kukhutshaziwe."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Zama futhi."</string>
@@ -1616,6 +1623,7 @@
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Ukulungiswa kombala"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Isinqamuleli sokufinyelela sivule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Isinqamuleli sokufinyelela sivale i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"Sebenzisa isinqamuleli sokufinyelela futhi ukuze uqale isici samanje sokufinyelela"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Khetha isici ozosisebenzisa uma uthepha inkinobho yokufinyelela:"</string>
     <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ukuze ushintshe izici, thinta uphinde ubambe inkinobho yokufinyelela."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ukukhuliswa"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 65b8807..cdb65ed 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1425,7 +1425,7 @@
              at {@link android.view.inputmethod.InputConnection#performEditorAction(int)
              InputConnection.performEditorAction(int)}.
              <p>Corresponds to
-             {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_FULLSCREEN}. -->
+             {@link android.view.inputmethod.EditorInfo#IME_FLAG_NAVIGATE_PREVIOUS}. -->
         <flag name="flagNavigatePrevious" value="0x4000000" />
         <!-- Used to specify that there is something
              interesting that a forward navigation can focus on. This is like using
@@ -4184,9 +4184,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.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3c0e51e..99af0de 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1102,6 +1102,10 @@
          <p>The default value of this attribute is <code>false</code>. -->
     <attr name="isFeatureSplit" format="boolean" />
 
+    <!-- Flag to specify if this APK requires at least one split [either feature or
+         resource] to be present in order to function. Default value is false. -->
+    <attr name="isSplitRequired" format="boolean" />
+
     <!-- Extra options for an activity's UI. Applies to either the {@code <activity>} or
          {@code <application>} tag. If specified on the {@code <application>}
          tag these will be considered defaults for all activities in the
@@ -1422,6 +1426,7 @@
         <attr name="targetSandboxVersion" />
         <attr name="compileSdkVersion" />
         <attr name="compileSdkVersionCodename" />
+        <attr name="isSplitRequired" />
     </declare-styleable>
 
     <!-- The <code>application</code> tag describes application-level components
@@ -1437,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">
@@ -1872,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/colors_car.xml b/core/res/res/values/colors_car.xml
index 6053728..32671ac8 100644
--- a/core/res/res/values/colors_car.xml
+++ b/core/res/res/values/colors_car.xml
@@ -17,15 +17,271 @@
  */
 -->
 <resources>
-  <!-- car support colors from
-  https://cs.corp.google.com/android/frameworks/support/car/res/values/colors.xml -->
-  <color name="car_user_switcher_user_image_bgcolor">@color/car_grey_50</color>
-  <color name="car_user_switcher_user_image_fgcolor">@color/car_grey_900</color>
-  <color name="car_card_dark">@color/car_dark_blue_grey_700</color>
-  <color name="car_body1_light">@color/car_grey_100</color>
+    <color name="car_background">@color/black</color>
 
-  <color name="car_grey_50">#fffafafa</color>
-  <color name="car_grey_900">#ff212121</color>
-  <color name="car_dark_blue_grey_700">#ff172026</color>
-  <color name="car_grey_100">#fff5f5f5</color>
+    <color name="car_colorPrimary">@color/car_grey_868</color>
+    <color name="car_colorSecondary">@color/car_grey_900</color>
+    <color name="car_colorPrimaryDark">@color/car_grey_958</color>
+
+
+    <!-- Various colors for text sizes. "Light" and "dark" here refer to the lighter or darker
+          shades. -->
+    <color name="car_title_light">@color/car_grey_100</color>
+    <color name="car_title_dark">@color/car_grey_900</color>
+    <color name="car_title">@color/car_title_light</color>
+
+    <color name="car_title2_light">@color/car_grey_100</color>
+    <color name="car_title2_dark">@color/car_grey_900</color>
+    <color name="car_title2">@color/car_title2_light</color>
+
+    <color name="car_headline1_light">@color/car_grey_100</color>
+    <color name="car_headline1_dark">@color/car_grey_800</color>
+    <color name="car_headline1">@color/car_headline1_light</color>
+
+    <color name="car_headline2_light">@color/car_grey_100</color>
+    <color name="car_headline2_dark">@color/car_grey_900</color>
+    <color name="car_headline2">@color/car_headline2_light</color>
+
+    <color name="car_headline3_light">@android:color/white</color>
+    <color name="car_headline3_dark">@color/car_grey_900</color>
+    <color name="car_headline3">@color/car_headline3_light</color>
+
+    <color name="car_headline4_light">@android:color/white</color>
+    <color name="car_headline4_dark">@android:color/black</color>
+    <color name="car_headline4">@color/car_headline4_light</color>
+
+    <color name="car_body1_light">@color/car_grey_100</color>
+    <color name="car_body1_dark">@color/car_grey_900</color>
+    <color name="car_body1">@color/car_body1_light</color>
+
+    <color name="car_body2_light">@color/car_grey_300</color>
+    <color name="car_body2_dark">@color/car_grey_700</color>
+    <color name="car_body2">@color/car_body2_light</color>
+
+    <color name="car_body3_light">@android:color/white</color>
+    <color name="car_body3_dark">@android:color/black</color>
+    <color name="car_body3">@color/car_body3_light</color>
+
+    <color name="car_body4_light">@android:color/white</color>
+    <color name="car_body4_dark">@android:color/black</color>
+    <color name="car_body4">@color/car_body4_light</color>
+
+    <color name="car_action1_light">@color/car_grey_900</color>
+    <color name="car_action1_dark">@color/car_grey_50</color>
+    <color name="car_action1">@color/car_action1_light</color>
+
+    <!-- The tinting colors to create a light- and dark-colored icon respectively. -->
+    <color name="car_tint_light">@color/car_grey_50</color>
+    <color name="car_tint_dark">@color/car_grey_900</color>
+
+    <!-- The tinting color for an icon. This icon is assumed to be on a light background. -->
+    <color name="car_tint">@color/car_tint_light</color>
+
+    <!-- An inverted tinting from car_tint. -->
+    <color name="car_tint_inverse">@color/car_tint_dark</color>
+
+    <!-- The color of the divider. The color here is a lighter shade. -->
+    <color name="car_list_divider_light">#1fffffff</color>
+
+    <!-- The color of the divider. The color here is a darker shade. -->
+    <color name="car_list_divider_dark">#1f000000</color>
+
+    <!-- The color of the dividers in the list. This color is assumed to be on a light colored
+         view. -->
+    <color name="car_list_divider">@color/car_list_divider_light</color>
+
+    <!-- A light and dark colored card. -->
+    <color name="car_card_light">@color/car_grey_50</color>
+    <color name="car_card_dark">@color/car_dark_blue_grey_700</color>
+
+    <!-- The default color of a card in car UI. -->
+    <color name="car_card">@color/car_card_dark</color>
+
+    <!-- The ripple colors. The "dark" and "light" designation here refers to the color of the
+         ripple  itself. -->
+    <color name="car_card_ripple_background_dark">#8F000000</color>
+    <color name="car_card_ripple_background_light">#27ffffff</color>
+
+    <!-- The ripple color for a light colored card. -->
+    <color name="car_card_ripple_background">@color/car_card_ripple_background_light</color>
+
+    <!-- The ripple color for a dark-colored card. This color is the opposite of
+         car_card_ripple_background. -->
+    <color name="car_card_ripple_background_inverse">@color/car_card_ripple_background_dark</color>
+
+    <!-- The top margin before the start of content in an application. -->
+    <dimen name="app_header_height">96dp</dimen>
+
+    <!-- The lighter and darker color for the scrollbar thumb. -->
+    <color name="car_scrollbar_thumb_light">#99ffffff</color>
+    <color name="car_scrollbar_thumb_dark">#7f0b0f12</color>
+
+    <!-- The color of the scroll bar indicator in the PagedListView. This color is assumed to be on
+         a light-colored background. -->
+    <color name="car_scrollbar_thumb">@color/car_scrollbar_thumb_light</color>
+
+    <!-- The inverted color of the scroll bar indicator. This color is always the opposite of
+         car_scrollbar_thumb. -->
+    <color name="car_scrollbar_thumb_inverse">@color/car_scrollbar_thumb_dark</color>
+
+    <!-- The color of the seekbar track secondary progress in SeekbarListItem. -->
+    <color name="car_seekbar_track_secondary_progress">@color/car_grey_500</color>
+
+    <!-- The lighter and darker color for the seekbar track background. -->
+    <color name="car_seekbar_track_background_light">@color/car_grey_400</color>
+    <color name="car_seekbar_track_background_dark">@color/car_grey_700</color>
+    <!-- The color of the seekbar track background in SeekbarListItem. This color is assumed to be
+         on a light-colored background. -->
+    <color name="car_seekbar_track_background">@color/car_seekbar_track_background_dark</color>
+    <!-- background is car_grey_868 with .9 alpha -->
+    <color name="car_toast_background">#E6282a2d</color>
+
+    <!-- Misc colors -->
+    <color name="car_highlight_light">@color/car_teal_700</color>
+    <color name="car_highlight_dark">@color/car_teal_200</color>
+    <color name="car_highlight">@color/car_highlight_dark</color>
+    <color name="car_accent_light">@color/car_highlight_light</color>
+    <color name="car_accent_dark">@color/car_highlight_dark</color>
+    <color name="car_accent">@color/car_highlight_dark</color>
+
+    <color name="car_user_switcher_user_image_bgcolor">@color/car_grey_50</color>
+    <color name="car_user_switcher_user_image_fgcolor">@color/car_grey_900</color>
+
+    <!-- Color palette for cars -->
+    <color name="car_grey_958">#ff0e1013</color>
+    <color name="car_grey_928">#ff17181b</color>
+    <color name="car_grey_900">#ff202124</color>
+    <color name="car_grey_868">#ff282a2d</color>
+    <color name="car_grey_846">#ff2e3234</color>
+    <color name="car_grey_800">#ff3c4043</color>
+    <color name="car_grey_772">#ff464a4d</color>
+    <color name="car_grey_746">#ff4d5256</color>
+    <color name="car_grey_700">#ff5f6368</color>
+    <color name="car_grey_600">#ff80868b</color>
+    <color name="car_grey_500">#ff9aa0a6</color>
+    <color name="car_grey_400">#ffbdc1c6</color>
+    <color name="car_grey_300">#ffdadce0</color>
+    <color name="car_grey_200">#ffe8eaed</color>
+    <color name="car_grey_100">#fff1f3f4</color>
+    <color name="car_grey_50">#fff8f9fa</color>
+
+    <color name="car_blue_900">#ff1d57a9</color>
+    <color name="car_blue_800">#ff2065bb</color>
+    <color name="car_blue_700">#ff2374ce</color>
+    <color name="car_blue_600">#ff2581df</color>
+    <color name="car_blue_500">#ff5195ea</color>
+    <color name="car_blue_400">#ff6ba5ed</color>
+    <color name="car_blue_300">#ff96bff2</color>
+    <color name="car_blue_200">#ffb9d4f6</color>
+    <color name="car_blue_100">#ffd9e6f9</color>
+    <color name="car_blue_50">#ffebf1fc</color>
+
+    <color name="car_green_900">#ff136e39</color>
+    <color name="car_green_800">#ff1b7e42</color>
+    <color name="car_green_700">#ff218c48</color>
+    <color name="car_green_600">#ff28994f</color>
+    <color name="car_green_500">#ff41af6a</color>
+    <color name="car_green_400">#ff5dba80</color>
+    <color name="car_green_300">#ff8dcfa5</color>
+    <color name="car_green_200">#ffb3dfc3</color>
+    <color name="car_green_100">#ffd5ebdf</color>
+    <color name="car_green_50">#ffe8f3ee</color>
+
+    <color name="car_red_900">#ffa81314</color>
+    <color name="car_red_800">#ffb41b1a</color>
+    <color name="car_red_700">#ffc22a2a</color>
+    <color name="car_red_600">#ffd33b30</color>
+    <color name="car_red_500">#ffe25142</color>
+    <color name="car_red_400">#ffe66a5e</color>
+    <color name="car_red_300">#ffed968d</color>
+    <color name="car_red_200">#fff3b9b3</color>
+    <color name="car_red_100">#fff7d8d9</color>
+    <color name="car_red_50">#fffaebeb</color>
+
+    <color name="car_yellow_900">#ffdd860e</color>
+    <color name="car_yellow_800">#ffe59810</color>
+    <color name="car_yellow_700">#ffeda912</color>
+    <color name="car_yellow_600">#fff3b713</color>
+    <color name="car_yellow_500">#fff5c518</color>
+    <color name="car_yellow_400">#fff6cd3a</color>
+    <color name="car_yellow_300">#fff9dc74</color>
+    <color name="car_yellow_200">#fffbe7a2</color>
+    <color name="car_yellow_100">#fffcf0ce</color>
+    <color name="car_yellow_50">#fffdf7e6</color>
+
+    <color name="car_orange_900">#ffb06000</color>
+    <color name="car_orange_800">#ffc26401</color>
+    <color name="car_orange_700">#ffd56e0c</color>
+    <color name="car_orange_600">#ffe8710a</color>
+    <color name="car_orange_500">#fffa7b17</color>
+    <color name="car_orange_400">#fffa903e</color>
+    <color name="car_orange_300">#fffcad70</color>
+    <color name="car_orange_200">#fffdc69c</color>
+    <color name="car_orange_100">#fffedfc8</color>
+    <color name="car_orange_50">#fffeefe3</color>
+
+    <color name="car_pink_900">#ff9c166b</color>
+    <color name="car_pink_800">#ffb80672</color>
+    <color name="car_pink_700">#ffd01884</color>
+    <color name="car_pink_600">#ffe52592</color>
+    <color name="car_pink_500">#fff439a0</color>
+    <color name="car_pink_400">#ffff63b8</color>
+    <color name="car_pink_300">#ffff8bcb</color>
+    <color name="car_pink_200">#fffba9d6</color>
+    <color name="car_pink_100">#fffdcfe8</color>
+    <color name="car_pink_50">#fffde7f3</color>
+
+    <color name="car_teal_900">#ff004d40</color>
+    <color name="car_teal_800">#ff00695c</color>
+    <color name="car_teal_700">#ff00796b</color>
+    <color name="car_teal_600">#ff00897b</color>
+    <color name="car_teal_500">#ff009688</color>
+    <color name="car_teal_400">#ff26a69a</color>
+    <color name="car_teal_300">#ff4db6ac</color>
+    <color name="car_teal_200">#ff80cbc4</color>
+    <color name="car_teal_100">#ffb2dfdb</color>
+    <color name="car_teal_50">#ffe0f2f1</color>
+
+    <color name="car_purple_900">#ff681da8</color>
+    <color name="car_purple_800">#ff7627bb</color>
+    <color name="car_purple_700">#ff8430ce</color>
+    <color name="car_purple_600">#ff9334e6</color>
+    <color name="car_purple_500">#ffa142f4</color>
+    <color name="car_purple_400">#ffaf5cf7</color>
+    <color name="car_purple_300">#ffc58af9</color>
+    <color name="car_purple_200">#ffd7aefb</color>
+    <color name="car_purple_100">#ffe9d2fd</color>
+    <color name="car_purple_50">#fff3e8fd</color>
+
+    <color name="car_cyan_900">#ff01877e</color>
+    <color name="car_cyan_800">#ff099091</color>
+    <color name="car_cyan_700">#ff12a4af</color>
+    <color name="car_cyan_600">#ff12b5cb</color>
+    <color name="car_cyan_500">#ff24c1e0</color>
+    <color name="car_cyan_400">#ff4ecde6</color>
+    <color name="car_cyan_300">#ff78d9ec</color>
+    <color name="car_cyan_200">#ffa1e4f2</color>
+    <color name="car_cyan_100">#ffcbf0f8</color>
+    <color name="car_cyan_50">#ffe4f7fb</color>
+
+
+    <color name="car_grey_1000">#cc000000</color>
+    <color name="car_white_1000">#1effffff</color>
+    <color name="car_blue_grey_800">#ff37474F</color>
+    <color name="car_blue_grey_900">#ff263238</color>
+    <color name="car_dark_blue_grey_600">#ff1d272d</color>
+    <color name="car_dark_blue_grey_700">#ff172026</color>
+    <color name="car_dark_blue_grey_800">#ff11181d</color>
+    <color name="car_dark_blue_grey_900">#ff0c1013</color>
+    <color name="car_dark_blue_grey_1000">#ff090c0f</color>
+    <color name="car_light_blue_300">#ff4fc3f7</color>
+    <color name="car_light_blue_500">#ff03A9F4</color>
+    <color name="car_light_blue_600">#ff039be5</color>
+    <color name="car_light_blue_700">#ff0288d1</color>
+    <color name="car_light_blue_800">#ff0277bd</color>
+    <color name="car_light_blue_900">#ff01579b</color>
+
+
+    <color name="car_red_500a">#ffd50000</color>
+    <color name="car_red_a700">#ffd50000</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1404383..8b73b67 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1527,7 +1527,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 +2113,8 @@
     <!-- Type of the long press sensor. Empty if long press is not supported. -->
     <string name="config_dozeLongPressSensorType" translatable="false"></string>
 
-    <!-- Type of the reach sensor. Empty if reach is not supported. -->
-    <string name="config_dozeReachSensorType" translatable="false"></string>
+    <!-- Type of sensor that wakes up the lock screen. Empty if not supported. -->
+    <string name="config_dozeWakeLockScreenSensorType" translatable="false"></string>
 
     <!-- Type of the wake up sensor. Empty if not supported. -->
     <string name="config_dozeWakeScreenSensorType" translatable="false"></string>
@@ -3541,4 +3541,16 @@
 
     <!-- Brand value for attestation of misprovisioned device. -->
     <string name="config_misprovisionedBrandValue" translatable="false"></string>
+
+    <!-- Pre-scale volume at volume step 1 for Absolute Volume -->
+    <fraction name="config_prescaleAbsoluteVolume_index1">50%</fraction>
+
+    <!-- Pre-scale volume at volume step 2 for Absolute Volume -->
+    <fraction name="config_prescaleAbsoluteVolume_index2">70%</fraction>
+
+    <!-- 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>
 </resources>
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
index 7d14f86..a0c02ed 100644
--- a/core/res/res/values/dimens_car.xml
+++ b/core/res/res/values/dimens_car.xml
@@ -16,12 +16,86 @@
 */
 -->
 <resources>
-    <!-- TODO replace with car support lib sizes when available -->
     <dimen name="car_fullscreen_user_pod_icon_text_size">64sp</dimen>
     <dimen name="car_fullscreen_user_pod_width">243dp</dimen>
     <dimen name="car_fullscreen_user_pod_height">356dp</dimen>
     <dimen name="car_fullscreen_user_pod_image_avatar_width">96dp</dimen>
     <dimen name="car_fullscreen_user_pod_image_avatar_height">96dp</dimen>
-    <dimen name="car_padding_4">20dp</dimen>
+
+
+    <!-- Application Bar -->
+    <dimen name="car_app_bar_height">80dp</dimen>
+    <!-- Margin -->
+    <dimen name="car_margin">20dp</dimen>
+    <!-- Lists -->
+    <dimen name="car_single_line_list_item_height">96dp</dimen>
+    <dimen name="car_double_line_list_item_height">@dimen/car_single_line_list_item_height</dimen>
+    <dimen name="car_list_divider_height">1dp</dimen>
+    <!-- The diff between keyline 1 and keyline 3. -->
+    <dimen name="car_keyline_1_keyline_3_diff">88dp</dimen>
+    <dimen name="car_dialog_action_bar_height">@dimen/car_card_action_bar_height</dimen>
+    <dimen name="car_primary_icon_size">44dp</dimen>
+
+    <!-- Text size for car -->
+    <dimen name="car_title_size">32sp</dimen>
+    <dimen name="car_title2_size">32sp</dimen>
+    <dimen name="car_headline1_size">45sp</dimen>
+    <dimen name="car_headline2_size">32sp</dimen>
+    <dimen name="car_headline3_size">24sp</dimen>
+    <dimen name="car_headline4_size">20sp</dimen>
     <dimen name="car_body1_size">32sp</dimen>
-</resources>
\ No newline at end of file
+    <dimen name="car_body2_size">26sp</dimen>
+    <dimen name="car_body3_size">16sp</dimen>
+    <dimen name="car_body4_size">14sp</dimen>
+    <dimen name="car_body5_size">18sp</dimen>
+    <dimen name="car_label1_size">26sp</dimen>
+    <dimen name="car_label2_size">64sp</dimen>
+    <dimen name="car_action1_size">26sp</dimen>
+    <dimen name="car_action2_size">26sp</dimen>
+
+    <!-- Common icon size for car app -->
+    <dimen name="car_icon_size">56dp</dimen>
+
+    <dimen name="car_card_header_height">96dp</dimen>
+    <dimen name="car_card_action_bar_height">96dp</dimen>
+
+    <!-- Paddings -->
+    <dimen name="car_padding_1">4dp</dimen>
+    <dimen name="car_padding_2">10dp</dimen>
+    <dimen name="car_padding_3">16dp</dimen>
+    <dimen name="car_padding_4">28dp</dimen>
+    <dimen name="car_padding_5">32dp</dimen>
+
+    <!-- Radius -->
+    <dimen name="car_radius_1">4dp</dimen>
+    <dimen name="car_radius_2">8dp</dimen>
+    <dimen name="car_radius_3">16dp</dimen>
+    <dimen name="car_radius_5">100dp</dimen>
+
+    <!-- Keylines for content. -->
+    <dimen name="car_keyline_1">48dp</dimen>
+    <dimen name="car_keyline_2">108dp</dimen>
+    <dimen name="car_keyline_3">152dp</dimen>
+    <dimen name="car_keyline_4">182dp</dimen>
+
+    <!-- Buttons -->
+    <dimen name="car_button_height">56dp</dimen>
+    <dimen name="car_button_min_width">158dp</dimen>
+    <dimen name="car_button_horizontal_padding">@dimen/car_padding_4</dimen>
+    <dimen name="car_borderless_button_horizontal_padding">0dp</dimen>
+    <dimen name="car_button_radius">@dimen/car_radius_1</dimen>
+    <dimen name="car_pill_button_size">56dp</dimen>
+
+    <!-- Seekbar -->
+    <dimen name="car_seekbar_height">6dp</dimen>
+    <dimen name="car_seekbar_padding">26dp</dimen>
+    <dimen name="car_seekbar_thumb_size">24dp</dimen>
+    <dimen name="car_seekbar_thumb_stroke">1dp</dimen>
+    <!-- The space between seekbar and text in ListItem. This value is based on car_seekbar_padding.
+         It brings seekbar and text closer for visual balance while maintaining touch area. -->
+    <dimen name="car_seekbar_text_overlap">-20dp</dimen>
+
+    <!-- Progress Bar -->
+    <dimen name="car_progress_bar_height">@dimen/car_seekbar_height</dimen>
+
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index cc99a4e..2e42e4a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2903,6 +2903,7 @@
   <eat-comment />
 
     <public-group type="attr" first-id="0x01010587">
+        <public name="packageType" />
         <public name="opticalInsetLeft" />
         <public name="opticalInsetTop" />
         <public name="opticalInsetRight" />
@@ -2912,6 +2913,8 @@
         <!-- @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-group>
 
     <public-group type="drawable" first-id="0x010800b4">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 64620f3..6bf893d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1132,9 +1132,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>
@@ -1418,6 +1418,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>
 
@@ -1439,6 +1442,10 @@
     <string name="biometric_not_recognized">Not recognized</string>
     <!-- Accessibility message announced when a fingerprint has been authenticated [CHAR LIMIT=NONE] -->
     <string name="fingerprint_authenticated">Fingerprint authenticated</string>
+    <!-- Accessibility message announced when a face has been authenticated [CHAR LIMIT=NONE] -->
+    <string name="face_authenticated_no_confirmation_required">Face authenticated</string>
+    <!-- Accessibility message announced when a face has been authenticated, but requires the user to press the confirm button [CHAR LIMIT=NONE] -->
+    <string name="face_authenticated_confirmation_required">Face authenticated, please press confirm</string>
 
     <!-- Error message shown when the fingerprint hardware can't be accessed -->
     <string name="fingerprint_error_hw_not_available">Fingerprint hardware not available.</string>
@@ -1516,6 +1523,8 @@
     <string name="face_error_no_space">Face can\u2019t be stored.</string>
     <!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
     <string name="face_error_canceled">Face operation canceled.</string>
+    <!-- Generic error message shown when the face authentication operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=50] -->
+    <string name="face_error_user_canceled">Face authentication canceled by user.</string>
     <!-- Generic error message shown when the face operation fails because too many attempts have been made. [CHAR LIMIT=50] -->
     <string name="face_error_lockout">Too many attempts. Try again later.</string>
     <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] -->
@@ -4999,33 +5008,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/styles_car.xml b/core/res/res/values/styles_car.xml
new file mode 100644
index 0000000..f6ff1b6
--- /dev/null
+++ b/core/res/res/values/styles_car.xml
@@ -0,0 +1,89 @@
+<?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>
+    <!-- Car text -->
+    <style name="CarBody1">
+        <item name="textStyle">normal</item>
+        <item name="textSize">@dimen/car_body1_size</item>
+        <item name="textColor">@color/car_body1</item>
+    </style>
+
+    <style name="CarBody1.Light">
+        <item name="textColor">@color/car_body1_light</item>
+    </style>
+
+    <style name="CarBody1.Dark">
+        <item name="textColor">@color/car_body2_dark</item>
+    </style>
+
+    <style name="CarBody2">
+        <item name="textStyle">normal</item>
+        <item name="textSize">@dimen/car_body2_size</item>
+        <item name="textColor">@color/car_body2</item>
+    </style>
+
+    <style name="CarBody2.Dark">
+        <item name="textColor">@color/car_body2_dark</item>
+    </style>
+    <style name="CarBody2.Light">
+        <item name="textColor">@color/car_body2_light</item>
+    </style>
+
+    <style name="CarBody3">
+        <item name="textStyle">normal</item>
+        <item name="textSize">@dimen/car_body3_size</item>
+        <item name="textColor">@color/car_body3</item>
+    </style>
+
+    <!-- The smallest styling for body text. The color of this text changes based on the day/night
+         mode. -->
+    <style name="CarBody4">
+        <item name="textStyle">normal</item>
+        <item name="textSize">@dimen/car_body4_size</item>
+        <item name="textColor">@color/car_body4</item>
+    </style>
+
+    <style name="CarAction1">
+        <item name="textStyle">bold</item>
+        <item name="textSize">@dimen/car_action1_size</item>
+        <item name="textColor">@color/car_highlight</item>
+    </style>
+
+    <style name="CarAction1.Dark">
+        <item name="textColor">@color/car_highlight_dark</item>
+    </style>
+    <style name="CarAction1.Light">
+        <item name="textColor">@color/car_highlight_light</item>
+    </style>
+
+    <!-- The styling for title text. The color of this text changes based on day/night mode. -->
+    <style name="CarTitle" >
+        <item name="textStyle">bold</item>
+        <item name="textSize">@dimen/car_title2_size</item>
+        <item name="textColor">@color/car_title</item>
+    </style>
+
+    <!-- Title text that is permanently a dark color. -->
+    <style name="CarTitle.Dark" >
+        <item name="textColor">@color/car_title_dark</item>
+    </style>
+
+    <!-- Title text that is permanently a light color. -->
+    <style name="CarTitle.Light" >
+        <item name="textColor">@color/car_title_light</item>
+    </style>
+
+</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7b8eced..7e7c7b2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2394,6 +2394,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" />
 
@@ -2429,6 +2430,7 @@
   <java-symbol type="string" name="face_error_timeout" />
   <java-symbol type="array" name="face_error_vendor" />
   <java-symbol type="string" name="face_error_canceled" />
+  <java-symbol type="string" name="face_error_user_canceled" />
   <java-symbol type="string" name="face_error_lockout" />
   <java-symbol type="string" name="face_error_lockout_permanent" />
   <java-symbol type="string" name="face_error_not_enrolled" />
@@ -2446,6 +2448,8 @@
   <java-symbol type="string" name="face_acquired_not_detected" />
   <java-symbol type="array" name="face_acquired_vendor" />
   <java-symbol type="string" name="face_name_template" />
+  <java-symbol type="string" name="face_authenticated_no_confirmation_required" />
+  <java-symbol type="string" name="face_authenticated_confirmation_required" />
 
   <!-- Face config -->
   <java-symbol type="integer" name="config_faceMaxTemplatesPerUser" />
@@ -3151,7 +3155,9 @@
   <java-symbol type="integer" name="autofill_max_visible_datasets" />
 
   <java-symbol type="style" name="Theme.DeviceDefault.Autofill" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Autofill" />
   <java-symbol type="style" name="Theme.DeviceDefault.Autofill.Save" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Autofill.Save" />
 
   <java-symbol type="dimen" name="notification_big_picture_max_height"/>
   <java-symbol type="dimen" name="notification_big_picture_max_width"/>
@@ -3274,7 +3280,7 @@
   <java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
 
   <java-symbol type="string" name="config_dozeLongPressSensorType" />
-  <java-symbol type="string" name="config_dozeReachSensorType" />
+  <java-symbol type="string" name="config_dozeWakeLockScreenSensorType" />
 
   <java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
   <java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
@@ -3465,4 +3471,11 @@
   <java-symbol type="integer" name="db_wal_truncate_size" />
   <java-symbol type="integer" name="config_wakeUpDelayDoze" />
   <java-symbol type="string" name="config_dozeWakeScreenSensorType" />
+
+  <!-- For Bluetooth AbsoluteVolume -->
+  <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" />
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 92096ab..3385527 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1681,13 +1681,14 @@
     </style>
 
 
-    <!-- @hide DeviceDefault theme for the autofill FillUi -->
-    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material.Autofill.Light">
-    </style>
+    <!-- @hide DeviceDefault themes for the autofill FillUi -->
+    <style name="Theme.DeviceDefault.Autofill" />
+    <style name="Theme.DeviceDefault.Light.Autofill" />
 
-    <!-- @hide DeviceDefault theme for the autofill SaveUi -->
-    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Autofill.Save.Light">
-    </style>
+    <!-- @hide DeviceDefault theme for the autofill SaveUi. NOTE: it must be a .Panel so the dialog
+         is shown at the bottom of the screen  -->
+    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.DeviceDefault.Panel"/>
+    <style name="Theme.DeviceDefault.Light.Autofill.Save" parent="Theme.DeviceDefault.Light.Panel"/>
 
     <!-- DeviceDefault theme for the default system theme.  -->
     <style name="Theme.DeviceDefault.System" parent="Theme.DeviceDefault.Light.DarkActionBar" />
@@ -1715,4 +1716,10 @@
         <item name="colorAccent">@color/accent_device_default_dark</item>
     </style>
 
+    <style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
+        <item name="colorBackground">@color/background_device_default_light</item>
+        <item name="colorBackgroundFloating">@color/background_device_default_light</item>
+        <item name="layout_gravity">center</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index b3e33d5..ccaf041 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -1418,24 +1418,4 @@
         <item name="colorSecondary">@color/secondary_material_settings</item>
     </style>
 
-    <!-- @hide -->
-    <style name="Theme.Material.Autofill" parent="Theme.Material">
-        <item name="colorBackground">@color/autofill_background_material_dark</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="Theme.Material.Autofill.Light" parent="Theme.Material.Light">
-        <item name="colorBackground">@color/autofill_background_material_light</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="Theme.Material.Autofill.Save" parent="Theme.Material.Panel">
-        <item name="colorBackground">@color/autofill_background_material_dark</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="Theme.Material.Autofill.Save.Light" parent="Theme.Material.Light.Panel">
-        <item name="colorBackground">@color/autofill_background_material_light</item>
-    </style>
-
 </resources>
diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml
index cb4e5c4..6cf6a82 100644
--- a/core/res/res/xml/default_zen_mode_config.xml
+++ b/core/res/res/xml/default_zen_mode_config.xml
@@ -18,13 +18,17 @@
 -->
 
 <!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
-<zen version="7">
+<zen version="8">
     <allow alarms="true" media="true" system="false" calls="true" callsFrom="2" messages="false"
            reminders="false" events="false" repeatCallers="true" />
-
+    <automatic ruleId="EVENTS_DEFAULT_RULE" enabled="false" snoozing="false" name="Event" zen="1"
+               component="android/com.android.server.notification.EventConditionProvider"
+               conditionId="condition://android/event?userId=-10000&amp;calendar=&amp;reply=1"/>
+    <automatic ruleId="EVERY_NIGHT_DEFAULT_RULE" enabled="false" snoozing="false" name="Sleeping"
+               zen="1" component="android/com.android.server.notification.ScheduleConditionProvider"
+               conditionId="condition://android/schedule?days=1.2.3.4.5.6.7&amp;start=22.0&amp;end=7.0&amp;exitAtAlarm=true"/>
     <!-- all visual effects that exist as of P -->
     <disallow visualEffects="511" />
-
     <!-- whether there are notification channels that can bypass dnd -->
     <state areChannelsBypassingDnd="false" />
 </zen>
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/src/android/content/ContentProviderTest.java b/core/tests/coretests/src/android/content/ContentProviderTest.java
new file mode 100644
index 0000000..2142f27
--- /dev/null
+++ b/core/tests/coretests/src/android/content/ContentProviderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.withSettings;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ProviderInfo;
+import android.net.Uri;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+
+@RunWith(AndroidJUnit4.class)
+public class ContentProviderTest {
+
+    private Context mContext;
+    private ContentProvider mCp;
+
+    private ApplicationInfo mProviderApp;
+    private ProviderInfo mProvider;
+
+    @Before
+    public void setUp() {
+        mProviderApp = new ApplicationInfo();
+        mProviderApp.uid = 10001;
+
+        mProvider = new ProviderInfo();
+        mProvider.authority = "com.example";
+        mProvider.applicationInfo = mProviderApp;
+
+        mContext = mock(Context.class);
+
+        mCp = mock(ContentProvider.class, withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS));
+        mCp.attachInfo(mContext, mProvider);
+    }
+
+    @Test
+    public void testValidateIncomingUri_Normal() throws Exception {
+        assertEquals(Uri.parse("content://com.example/"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example/")));
+        assertEquals(Uri.parse("content://com.example/foo/bar"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example/foo/bar")));
+        assertEquals(Uri.parse("content://com.example/foo%2Fbar"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example/foo%2Fbar")));
+        assertEquals(Uri.parse("content://com.example/foo%2F%2Fbar"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example/foo%2F%2Fbar")));
+    }
+
+    @Test
+    public void testValidateIncomingUri_Shady() throws Exception {
+        assertEquals(Uri.parse("content://com.example/"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example//")));
+        assertEquals(Uri.parse("content://com.example/foo/bar/"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example//foo//bar//")));
+        assertEquals(Uri.parse("content://com.example/foo/bar/"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example/foo///bar/")));
+        assertEquals(Uri.parse("content://com.example/foo%2F%2Fbar/baz"),
+                mCp.validateIncomingUri(Uri.parse("content://com.example/foo%2F%2Fbar//baz")));
+    }
+
+    @Test
+    public void testValidateIncomingUri_NonPath() throws Exception {
+        // We only touch paths; queries and fragments are left intact
+        assertEquals(Uri.parse("content://com.example/foo/bar?foo=b//ar#foo=b//ar"),
+                mCp.validateIncomingUri(
+                        Uri.parse("content://com.example/foo/bar?foo=b//ar#foo=b//ar")));
+    }
+}
diff --git a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
index 3ce2589..6fdb71f 100644
--- a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
+++ b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.res.AssetManager;
 import android.graphics.fonts.Font;
+import android.graphics.fonts.FontCustomizationParser;
 import android.graphics.fonts.FontFamily;
 import android.graphics.fonts.SystemFonts;
 import android.support.test.InstrumentationRegistry;
@@ -36,12 +37,15 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
@@ -62,6 +66,8 @@
     };
     private static final String TEST_FONTS_XML;
     private static final String TEST_FONT_DIR;
+    private static final String TEST_OEM_XML;
+    private static final String TEST_OEM_DIR;
 
     private static final float GLYPH_1EM_WIDTH;
     private static final float GLYPH_2EM_WIDTH;
@@ -73,8 +79,13 @@
         if (!cacheDir.isDirectory()) {
             cacheDir.mkdirs();
         }
-        TEST_FONT_DIR = cacheDir.getAbsolutePath() + "/";
+        TEST_FONT_DIR = cacheDir.getAbsolutePath() + "/fonts/";
         TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath();
+        TEST_OEM_DIR = cacheDir.getAbsolutePath() + "/oem_fonts/";
+        TEST_OEM_XML = new File(cacheDir, "fonts_customization.xml").getAbsolutePath();
+
+        new File(TEST_FONT_DIR).mkdirs();
+        new File(TEST_OEM_DIR).mkdirs();
 
         final AssetManager am =
                 InstrumentationRegistry.getInstrumentation().getContext().getAssets();
@@ -99,6 +110,12 @@
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }
+            final File outOemInCache = new File(TEST_OEM_DIR, fontFile);
+            try (InputStream is = am.open(sourceInAsset)) {
+                Files.copy(is, outOemInCache.toPath(), StandardCopyOption.REPLACE_EXISTING);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
         }
     }
 
@@ -107,11 +124,14 @@
         for (final String fontFile : TEST_FONT_FILES) {
             final File outInCache = new File(TEST_FONT_DIR, fontFile);
             outInCache.delete();
+            final File outOemInCache = new File(TEST_OEM_DIR, fontFile);
+            outInCache.delete();
         }
     }
 
     private static void buildSystemFallback(String xml,
-            ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
+            FontCustomizationParser.Result oemCustomization, ArrayMap<String, Typeface> fontMap,
+            ArrayMap<String, FontFamily[]> fallbackMap) {
         final ArrayList<Font> availableFonts = new ArrayList<>();
         try (FileOutputStream fos = new FileOutputStream(TEST_FONTS_XML)) {
             fos.write(xml.getBytes(Charset.forName("UTF-8")));
@@ -119,18 +139,28 @@
             throw new RuntimeException(e);
         }
         final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(TEST_FONTS_XML,
-                TEST_FONT_DIR, fallbackMap, availableFonts);
+                TEST_FONT_DIR, oemCustomization, fallbackMap, availableFonts);
         Typeface.initSystemDefaultTypefaces(fontMap, fallbackMap, aliases);
     }
 
+    private static FontCustomizationParser.Result readFontCustomization(String oemXml) {
+        try (InputStream is = new ByteArrayInputStream(oemXml.getBytes(StandardCharsets.UTF_8))) {
+            return FontCustomizationParser.parse(is, TEST_OEM_DIR);
+        } catch (IOException | XmlPullParserException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     @Test
     public void testBuildSystemFallback() {
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
         final ArrayList<Font> availableFonts = new ArrayList<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
         final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(SYSTEM_FONTS_XML,
-                SYSTEM_FONT_DIR, fallbackMap, availableFonts);
+                SYSTEM_FONT_DIR, oemCustomization, fallbackMap, availableFonts);
 
         assertNotNull(aliases);
         assertFalse(fallbackMap.isEmpty());
@@ -156,8 +186,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         assertEquals(1, fontMap.size());
         assertTrue(fontMap.containsKey("sans-serif"));
@@ -184,8 +216,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -230,8 +264,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -275,8 +311,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -325,8 +363,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -371,8 +411,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -410,8 +452,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -449,8 +493,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -497,8 +543,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
         paint.setTypeface(fontMap.get("sans-serif"));
@@ -539,8 +587,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -578,8 +628,10 @@
                 + "</familyset>";
         final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
 
-        buildSystemFallback(xml, fontMap, fallbackMap);
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
 
         final Paint paint = new Paint();
 
@@ -598,4 +650,191 @@
         assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
     }
 
+    @Test
+    public void testBuildSystemFallback__Customization_new_named_family() {
+        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<familyset>"
+                + "  <family name='sans-serif'>"
+                + "    <font weight='400' style='normal'>a3em.ttf</font>"
+                + "  </family>"
+                + "</familyset>";
+        final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<fonts-modification version='1'>"
+                + "  <family customizationType='new-named-family' name='google-sans'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "  </family>"
+                + "</fonts-modification>";
+        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                readFontCustomization(oemXml);
+
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
+
+        final Paint paint = new Paint();
+
+        Typeface testTypeface = fontMap.get("sans-serif");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+        testTypeface = fontMap.get("google-sans");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+    }
+
+    @Test
+    public void testBuildSystemFallback__Customization_new_named_family_override() {
+        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<familyset>"
+                + "  <family name='sans-serif'>"
+                + "    <font weight='400' style='normal'>a3em.ttf</font>"
+                + "  </family>"
+                + "</familyset>";
+        final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<fonts-modification version='1'>"
+                + "  <family customizationType='new-named-family' name='sans-serif'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "  </family>"
+                + "</fonts-modification>";
+        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                readFontCustomization(oemXml);
+
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
+
+        final Paint paint = new Paint();
+
+        Typeface testTypeface = fontMap.get("sans-serif");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+    }
+
+    @Test
+    public void testBuildSystemFallback__Customization_additional_alias() {
+        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<familyset>"
+                + "  <family name='sans-serif'>"
+                + "    <font weight='400' style='normal'>a3em.ttf</font>"
+                + "  </family>"
+                + "</familyset>";
+        final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<fonts-modification version='1'>"
+                + "  <family customizationType='new-named-family' name='google-sans'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "    <font weight='700' style='normal'>c3em.ttf</font>"
+                + "  </family>"
+                + "  <alias name='another-google-sans' to='google-sans' />"
+                + "  <alias name='google-sans-bold' to='google-sans' weight='700' />"
+                + "</fonts-modification>";
+        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                readFontCustomization(oemXml);
+
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
+
+        final Paint paint = new Paint();
+
+        Typeface testTypeface = fontMap.get("sans-serif");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+        testTypeface = fontMap.get("google-sans");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+        testTypeface = fontMap.get("another-google-sans");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+        testTypeface = fontMap.get("google-sans-bold");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
+    }
+
+    @Test
+    public void testBuildSystemFallback__Customization_additional_alias_conflict_with_new_name() {
+        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<familyset>"
+                + "  <family name='named-family'>"
+                + "    <font weight='400' style='normal'>a3em.ttf</font>"
+                + "  </family>"
+                + "  <alias name='named-alias' to='named-family' />"
+                + "</familyset>";
+        final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<fonts-modification version='1'>"
+                + "  <family customizationType='new-named-family' name='named-alias'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "  </family>"
+                + "</fonts-modification>";
+        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+        final FontCustomizationParser.Result oemCustomization =
+                readFontCustomization(oemXml);
+
+        buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
+
+        final Paint paint = new Paint();
+
+        Typeface testTypeface = fontMap.get("named-family");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+        testTypeface = fontMap.get("named-alias");
+        assertNotNull(testTypeface);
+        paint.setTypeface(testTypeface);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildSystemFallback__Customization_new_named_family_no_name_exception() {
+        final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<fonts-modification version='1'>"
+                + "  <family customizationType='new-named-family'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "  </family>"
+                + "</fonts-modification>";
+        readFontCustomization(oemXml);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildSystemFallback__Customization_new_named_family_dup_name_exception() {
+        final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<fonts-modification version='1'>"
+                + "  <family customizationType='new-named-family' name='google-sans'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "  </family>"
+                + "  <family customizationType='new-named-family' name='google-sans'>"
+                + "    <font weight='400' style='normal'>b3em.ttf</font>"
+                + "  </family>"
+                + "</fonts-modification>";
+        readFontCustomization(oemXml);
+    }
 }
diff --git a/core/tests/coretests/src/android/net/LocalSocketTest.java b/core/tests/coretests/src/android/net/LocalSocketTest.java
index 1349844..1286b13 100644
--- a/core/tests/coretests/src/android/net/LocalSocketTest.java
+++ b/core/tests/coretests/src/android/net/LocalSocketTest.java
@@ -22,6 +22,7 @@
 import android.net.LocalSocketAddress;
 import android.test.MoreAsserts;
 import android.test.suitebuilder.annotation.SmallTest;
+
 import junit.framework.TestCase;
 
 import java.io.FileDescriptor;
@@ -39,6 +40,20 @@
 
         ls = new LocalSocket();
 
+        try {
+            ls.connect(new LocalSocketAddress(null));
+            fail("Expected NullPointerException");
+        } catch (NullPointerException e) {
+            // pass
+        }
+
+        try {
+            ls.bind(new LocalSocketAddress(null));
+            fail("Expected NullPointerException");
+        } catch (NullPointerException e) {
+            // pass
+        }
+
         ls.connect(new LocalSocketAddress("android.net.LocalSocketTest"));
 
         ls1 = ss.accept();
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 fee470d..60abd94 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -114,6 +114,7 @@
                     Settings.Global.ANOMALY_CONFIG_VERSION,
                     Settings.Global.APN_DB_UPDATE_CONTENT_URL,
                     Settings.Global.APN_DB_UPDATE_METADATA_URL,
+                    Settings.Global.APP_BINDING_CONSTANTS,
                     Settings.Global.APP_IDLE_CONSTANTS,
                     Settings.Global.APP_OPS_CONSTANTS,
                     Settings.Global.APP_STANDBY_ENABLED,
@@ -396,6 +397,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,
@@ -447,6 +449,7 @@
                     Settings.Global.ENABLE_GPU_DEBUG_LAYERS,
                     Settings.Global.GPU_DEBUG_APP,
                     Settings.Global.GPU_DEBUG_LAYERS,
+                    Settings.Global.ANGLE_ENABLED_APP,
                     Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
                     Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
                     Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS,
@@ -461,6 +464,7 @@
                     Settings.Global.WFC_IMS_MODE,
                     Settings.Global.WFC_IMS_ROAMING_ENABLED,
                     Settings.Global.WFC_IMS_ROAMING_MODE,
+                    Settings.Global.WIFI_ALWAYS_REQUESTED,
                     Settings.Global.WIFI_BADGING_THRESHOLDS,
                     Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS,
                     Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
@@ -539,6 +543,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/provider/SettingsValidatorsTest.java b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
index 8909293..b0d29bd 100644
--- a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
@@ -73,7 +73,7 @@
     @Test
     public void testComponentNameValidator() {
         assertTrue(SettingsValidators.COMPONENT_NAME_VALIDATOR.validate(
-                "android/com.android.internal.backup.LocalTransport"));
+                "com.android.localtransport/.LocalTransport"));
         assertFalse(SettingsValidators.COMPONENT_NAME_VALIDATOR.validate("rectangle"));
     }
 
@@ -90,7 +90,7 @@
     @Test
     public void testNullableComponentNameValidator_onValidComponentName_returnsTrue() {
         assertTrue(SettingsValidators.NULLABLE_COMPONENT_NAME_VALIDATOR.validate(
-                "android/com.android.internal.backup.LocalTransport"));
+                "com.android.localtransport/.LocalTransport"));
     }
 
     @Test
@@ -185,7 +185,7 @@
     @Test
     public void testComponentNameListValidator() {
         Validator v = new SettingsValidators.ComponentNameListValidator(",");
-        assertTrue(v.validate("android/com.android.internal.backup.LocalTransport,"
+        assertTrue(v.validate("com.android.localtransport/.LocalTransport,"
                 + "com.google.android.gms/.backup.migrate.service.D2dTransport"));
         assertFalse(v.validate("com.google.5android,android"));
     }
@@ -200,7 +200,7 @@
     @Test
     public void testPackageNameListValidator() {
         Validator v = new SettingsValidators.PackageNameListValidator(",");
-        assertTrue(v.validate("com.android.internal.backup.LocalTransport,com.google.android.gms"));
+        assertTrue(v.validate("com.android.localtransport.LocalTransport,com.google.android.gms"));
         assertFalse(v.validate("5com.android.internal.backup.LocalTransport,android"));
     }
 
diff --git a/core/tests/coretests/src/android/text/FontFallbackSetup.java b/core/tests/coretests/src/android/text/FontFallbackSetup.java
index 898e78c..5592aac 100644
--- a/core/tests/coretests/src/android/text/FontFallbackSetup.java
+++ b/core/tests/coretests/src/android/text/FontFallbackSetup.java
@@ -21,6 +21,7 @@
 import android.content.res.AssetManager;
 import android.graphics.Typeface;
 import android.graphics.fonts.Font;
+import android.graphics.fonts.FontCustomizationParser;
 import android.graphics.fonts.FontFamily;
 import android.graphics.fonts.SystemFonts;
 import android.support.test.InstrumentationRegistry;
@@ -77,8 +78,10 @@
 
         final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
         final ArrayList<Font> availableFonts = new ArrayList<>();
+        final FontCustomizationParser.Result oemCustomization =
+                new FontCustomizationParser.Result();
         final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(testFontsXml,
-                mTestFontsDir, fallbackMap, availableFonts);
+                mTestFontsDir, oemCustomization, fallbackMap, availableFonts);
         Typeface.initSystemDefaultTypefaces(mFontMap, fallbackMap, aliases);
     }
 
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index fe45fe7..c8d994c 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,83 @@
 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 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 +149,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 +200,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 +282,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 +336,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/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/inputmethod/InputMethodManagerTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodManagerTest.java
new file mode 100644
index 0000000..55e5e36
--- /dev/null
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodManagerTest.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 android.view.inputmethod;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+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 InputMethodManagerTest {
+    @Test
+    public void testPrivateApiGetInstance() throws Exception {
+        final InputMethodManager globalImm = InputMethodManager.getInstance();
+        assertNotNull("InputMethodManager.getInstance() still needs to work due to"
+                + " @UnsupportedAppUsage", globalImm);
+        assertEquals("InputMethodManager.peekInstance() still needs to work due to"
+                + " @UnsupportedAppUsage", globalImm, InputMethodManager.peekInstance());
+
+        final Context testContext = InstrumentationRegistry.getInstrumentation()
+                .getTargetContext();
+
+        final WindowManager wm = testContext.getSystemService(WindowManager.class);
+        final Context defaultDisplayContext =
+                testContext.createDisplayContext(wm.getDefaultDisplay());
+        final InputMethodManager imm =
+                defaultDisplayContext.getSystemService(InputMethodManager.class);
+        assertEquals("InputMethodManager.getInstance() always returns the instance for the default"
+                + " display.", globalImm, imm);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
index efdd7e9..8360126 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
@@ -43,7 +43,7 @@
 /**
  * Test class for {@link KernelCpuProcReader}.
  *
- * $ atest FrameworksCoreTests:com.android.internal.os.KernelCpuProcReader
+ * $ atest FrameworksCoreTests:com.android.internal.os.KernelCpuProcReaderTest
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
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 565a3ec..0c8dd9d 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.Message;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -74,14 +75,17 @@
     public void testSingleMessageDispatched() {
         TestableLooperStats looperStats = new TestableLooperStats(1, 100);
 
+        Message message = mHandlerFirst.obtainMessage(1000);
+        message.workSourceUid = 1000;
         Object token = looperStats.messageDispatchStarting();
         looperStats.tickRealtime(100);
         looperStats.tickThreadTime(10);
-        looperStats.messageDispatched(token, mHandlerFirst.obtainMessage(1000));
+        looperStats.messageDispatched(token, message);
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
         assertThat(entries).hasSize(1);
         LooperStats.ExportedEntry entry = entries.get(0);
+        assertThat(entry.workSourceUid).isEqualTo(1000);
         assertThat(entry.threadName).isEqualTo("TestThread1");
         assertThat(entry.handlerClassName).isEqualTo(
                 "com.android.internal.os.LooperStatsTest$TestHandlerFirst");
@@ -100,15 +104,17 @@
     public void testThrewException() {
         TestableLooperStats looperStats = new TestableLooperStats(1, 100);
 
+        Message message = mHandlerFirst.obtainMessage(7);
+        message.workSourceUid = 123;
         Object token = looperStats.messageDispatchStarting();
         looperStats.tickRealtime(100);
         looperStats.tickThreadTime(10);
-        looperStats.dispatchingThrewException(token, mHandlerFirst.obtainMessage(7),
-                new ArithmeticException());
+        looperStats.dispatchingThrewException(token, message, new ArithmeticException());
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
         assertThat(entries).hasSize(1);
         LooperStats.ExportedEntry entry = entries.get(0);
+        assertThat(entry.workSourceUid).isEqualTo(123);
         assertThat(entry.threadName).isEqualTo("TestThread1");
         assertThat(entry.handlerClassName).isEqualTo(
                 "com.android.internal.os.LooperStatsTest$TestHandlerFirst");
@@ -146,31 +152,39 @@
         looperStats.messageDispatched(token3, mHandlerSecond.obtainMessage().setCallback(() -> {
         }));
 
-        // Contributes to entry1.
+        // Will not be sampled so does not contribute to any entries.
         Object token4 = looperStats.messageDispatchStarting();
+        looperStats.tickRealtime(10);
+        looperStats.tickThreadTime(10);
+        looperStats.messageDispatched(token4, mHandlerSecond.obtainMessage(0));
+
+        // Contributes to entry1.
+        Object token5 = looperStats.messageDispatchStarting();
         looperStats.tickRealtime(100);
         looperStats.tickThreadTime(100);
-        looperStats.messageDispatched(token4, mHandlerAnonymous.obtainMessage(1));
+        looperStats.messageDispatched(token5, mHandlerAnonymous.obtainMessage(1));
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
         assertThat(entries).hasSize(3);
         entries.sort(Comparator.comparing(e -> e.handlerClassName));
 
-        // Captures data for token4 call.
+        // Captures data for token5 call.
         LooperStats.ExportedEntry entry1 = entries.get(0);
+        assertThat(entry1.workSourceUid).isEqualTo(-1);
         assertThat(entry1.threadName).isEqualTo("TestThread1");
         assertThat(entry1.handlerClassName).isEqualTo("com.android.internal.os.LooperStatsTest$1");
         assertThat(entry1.messageName).isEqualTo("0x1" /* 1 in hex */);
         assertThat(entry1.messageCount).isEqualTo(1);
-        assertThat(entry1.recordedMessageCount).isEqualTo(0);
+        assertThat(entry1.recordedMessageCount).isEqualTo(1);
         assertThat(entry1.exceptionCount).isEqualTo(0);
-        assertThat(entry1.totalLatencyMicros).isEqualTo(0);
-        assertThat(entry1.maxLatencyMicros).isEqualTo(0);
-        assertThat(entry1.cpuUsageMicros).isEqualTo(0);
-        assertThat(entry1.maxCpuUsageMicros).isEqualTo(0);
+        assertThat(entry1.totalLatencyMicros).isEqualTo(100);
+        assertThat(entry1.maxLatencyMicros).isEqualTo(100);
+        assertThat(entry1.cpuUsageMicros).isEqualTo(100);
+        assertThat(entry1.maxCpuUsageMicros).isEqualTo(100);
 
         // Captures data for token1 and token2 calls.
         LooperStats.ExportedEntry entry2 = entries.get(1);
+        assertThat(entry2.workSourceUid).isEqualTo(-1);
         assertThat(entry2.threadName).isEqualTo("TestThread1");
         assertThat(entry2.handlerClassName).isEqualTo(
                 "com.android.internal.os.LooperStatsTest$TestHandlerFirst");
@@ -185,6 +199,7 @@
 
         // Captures data for token3 call.
         LooperStats.ExportedEntry entry3 = entries.get(2);
+        assertThat(entry3.workSourceUid).isEqualTo(-1);
         assertThat(entry3.threadName).isEqualTo("TestThread2");
         assertThat(entry3.handlerClassName).isEqualTo(
                 "com.android.internal.os.LooperStatsTest$TestHandlerSecond");
@@ -265,7 +280,7 @@
 
     @Test
     public void testMessagesOverSizeCap() {
-        TestableLooperStats looperStats = new TestableLooperStats(2, 1 /* sizeCap */);
+        TestableLooperStats looperStats = new TestableLooperStats(1, 1 /* sizeCap */);
 
         Object token1 = looperStats.messageDispatchStarting();
         looperStats.tickRealtime(100);
@@ -296,12 +311,12 @@
         assertThat(entry1.handlerClassName).isEqualTo("");
         assertThat(entry1.messageName).isEqualTo("OVERFLOW");
         assertThat(entry1.messageCount).isEqualTo(3);
-        assertThat(entry1.recordedMessageCount).isEqualTo(1);
+        assertThat(entry1.recordedMessageCount).isEqualTo(3);
         assertThat(entry1.exceptionCount).isEqualTo(0);
-        assertThat(entry1.totalLatencyMicros).isEqualTo(10);
-        assertThat(entry1.maxLatencyMicros).isEqualTo(10);
-        assertThat(entry1.cpuUsageMicros).isEqualTo(10);
-        assertThat(entry1.maxCpuUsageMicros).isEqualTo(10);
+        assertThat(entry1.totalLatencyMicros).isEqualTo(70);
+        assertThat(entry1.maxLatencyMicros).isEqualTo(50);
+        assertThat(entry1.cpuUsageMicros).isEqualTo(40);
+        assertThat(entry1.maxCpuUsageMicros).isEqualTo(20);
 
         LooperStats.ExportedEntry entry2 = entries.get(1);
         assertThat(entry2.threadName).isEqualTo("TestThread1");
diff --git a/core/tests/coretests/src/com/android/internal/os/StoragedUidIoStatsReaderTest.java b/core/tests/coretests/src/com/android/internal/os/StoragedUidIoStatsReaderTest.java
new file mode 100644
index 0000000..c051a1c
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/StoragedUidIoStatsReaderTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.content.Context;
+import android.os.FileUtils;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.nio.file.Files;
+
+
+/**
+ * Test class for {@link StoragedUidIoStatsReader}.
+ *
+ * To run it:
+ * atest FrameworksCoreTests:com.android.internal.os.StoragedUidIoStatsReaderTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StoragedUidIoStatsReaderTest {
+
+    private File mRoot;
+    private File mTestDir;
+    private File mTestFile;
+    // private Random mRand = new Random();
+
+    private StoragedUidIoStatsReader mStoragedUidIoStatsReader;
+    @Mock
+    private StoragedUidIoStatsReader.Callback mCallback;
+
+    private Context getContext() {
+        return InstrumentationRegistry.getContext();
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mTestDir = getContext().getDir("test", Context.MODE_PRIVATE);
+        mRoot = getContext().getFilesDir();
+        mTestFile = new File(mTestDir, "test.file");
+        mStoragedUidIoStatsReader = new StoragedUidIoStatsReader(mTestFile.getAbsolutePath());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        FileUtils.deleteContents(mTestDir);
+        FileUtils.deleteContents(mRoot);
+    }
+
+
+    /**
+     * Tests that reading will never call the callback.
+     */
+    @Test
+    public void testReadNonexistentFile() throws Exception {
+        mStoragedUidIoStatsReader.readAbsolute(mCallback);
+        verifyZeroInteractions(mCallback);
+
+    }
+
+    /**
+     * Tests that reading a file with 3 uids works as expected.
+     */
+    @Test
+    public void testReadExpected() throws Exception {
+        BufferedWriter bufferedWriter = Files.newBufferedWriter(mTestFile.toPath());
+        int[] uids = {0, 100, 200};
+        long[] fg_chars_read = {1L, 101L, 201L};
+        long[] fg_chars_write = {2L, 102L, 202L};
+        long[] fg_bytes_read = {3L, 103L, 203L};
+        long[] fg_bytes_write = {4L, 104L, 204L};
+        long[] bg_chars_read = {5L, 105L, 205L};
+        long[] bg_chars_write = {6L, 106L, 206L};
+        long[] bg_bytes_read = {7L, 107L, 207L};
+        long[] bg_bytes_write = {8L, 108L, 208L};
+        long[] fg_fsync = {9L, 109L, 209L};
+        long[] bg_fsync = {10L, 110L, 210L};
+
+        for (int i = 0; i < uids.length; i++) {
+            bufferedWriter.write(String
+                    .format("%d %d %d %d %d %d %d %d %d %d %d\n", uids[i], fg_chars_read[i],
+                            fg_chars_write[i], fg_bytes_read[i], fg_bytes_write[i],
+                            bg_chars_read[i], bg_chars_write[i], bg_bytes_read[i],
+                            bg_bytes_write[i], fg_fsync[i], bg_fsync[i]));
+        }
+        bufferedWriter.close();
+
+        mStoragedUidIoStatsReader.readAbsolute(mCallback);
+        for (int i = 0; i < uids.length; i++) {
+            verify(mCallback).onUidStorageStats(uids[i], fg_chars_read[i], fg_chars_write[i],
+                    fg_bytes_read[i], fg_bytes_write[i], bg_chars_read[i], bg_chars_write[i],
+                    bg_bytes_read[i], bg_bytes_write[i], fg_fsync[i], bg_fsync[i]);
+        }
+        verifyNoMoreInteractions(mCallback);
+
+    }
+
+    /**
+     * Tests that a line with less than 11 items is passed over.
+     */
+    @Test
+    public void testLineDoesNotElevenEntries() throws Exception {
+        BufferedWriter bufferedWriter = Files.newBufferedWriter(mTestFile.toPath());
+
+        // Only has 10 numbers.
+        bufferedWriter.write(String
+                .format("%d %d %d %d %d %d %d %d %d %d\n", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
+
+        bufferedWriter.write(String
+                .format("%d %d %d %d %d %d %d %d %d %d %d\n", 10, 11, 12, 13, 14, 15, 16, 17, 18,
+                        19, 20));
+        bufferedWriter.close();
+
+        // Make sure we get the second line, but the first is skipped.
+        mStoragedUidIoStatsReader.readAbsolute(mCallback);
+        verify(mCallback).onUidStorageStats(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
+        verifyNoMoreInteractions(mCallback);
+    }
+
+
+    /**
+     * Tests that a line that is malformed is passed over.
+     */
+    @Test
+    public void testLineIsMalformed() throws Exception {
+        BufferedWriter bufferedWriter = Files.newBufferedWriter(mTestFile.toPath());
+
+        // Line is not formatted properly. It has a string.
+        bufferedWriter.write(String
+                .format("%d %d %d %d %d %s %d %d %d %d %d\n", 0, 1, 2, 3, 4, "NotANumber", 5, 6, 7,
+                        8, 9));
+
+        bufferedWriter.write(String
+                .format("%d %d %d %d %d %d %d %d %d %d %d\n", 10, 11, 12, 13, 14, 15, 16, 17, 18,
+                        19, 20));
+        bufferedWriter.close();
+
+        // Make sure we get the second line, but the first is skipped.
+        mStoragedUidIoStatsReader.readAbsolute(mCallback);
+        verify(mCallback).onUidStorageStats(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
+        verifyNoMoreInteractions(mCallback);
+    }
+}
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/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
index ae6a7f6..b0d2de1 100644
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -28,7 +28,7 @@
     <!-- Whitelist of what components are permitted as backup data transports.  The
          'service' attribute here is a flattened ComponentName string. -->
     <backup-transport-whitelisted-service
-        service="android/com.android.internal.backup.LocalTransportService" />
+        service="com.android.localtransport/.LocalTransportService" />
 
     <!-- Whitelist of bundled applications which all handle URLs to their websites by default -->
     <app-link package="com.android.carrierdefaultapp" />
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 76eb4e6..454dceb 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -89,23 +89,7 @@
 
 LOCAL_MODULE := fonts.xml
 LOCAL_MODULE_CLASS := ETC
-
-AOSP_FONTS_FILE := frameworks/base/data/fonts/fonts.xml
-
-ifdef ADDITIONAL_FONTS_FILE
-ADDITIONAL_FONTS_SCRIPT := frameworks/base/tools/fonts/add_additional_fonts.py
-ADD_ADDITIONAL_FONTS := $(local-generated-sources-dir)/fonts.xml
-
-$(ADD_ADDITIONAL_FONTS): PRIVATE_SCRIPT := $(ADDITIONAL_FONTS_SCRIPT)
-$(ADD_ADDITIONAL_FONTS): PRIVATE_ADDITIONAL_FONTS_FILE := $(ADDITIONAL_FONTS_FILE)
-$(ADD_ADDITIONAL_FONTS): $(ADDITIONAL_FONTS_SCRIPT) $(AOSP_FONTS_FILE) $(ADDITIONAL_FONTS_FILE)
-	rm -f $@
-	python $(PRIVATE_SCRIPT) $@ $(PRIVATE_ADDITIONAL_FONTS_FILE)
-else
-ADD_ADDITIONAL_FONTS := $(AOSP_FONTS_FILE)
-endif
-
-LOCAL_PREBUILT_MODULE_FILE := $(ADD_ADDITIONAL_FONTS)
+LOCAL_PREBUILT_MODULE_FILE := frameworks/base/data/fonts/fonts.xml
 
 include $(BUILD_PREBUILT)
 
diff --git a/data/keyboards/Vendor_054c_Product_0268.kl b/data/keyboards/Vendor_054c_Product_0268.kl
index 522db3c..b463dd8 100644
--- a/data/keyboards/Vendor_054c_Product_0268.kl
+++ b/data/keyboards/Vendor_054c_Product_0268.kl
@@ -21,8 +21,6 @@
 key 0x126    DPAD_DOWN
 key 0x127    DPAD_LEFT
 
-key 0x120    BUTTON_SELECT
-key 0x123    BUTTON_START
 key 0x12e    BUTTON_A
 key 0x12d    BUTTON_B
 key 0x12f    BUTTON_X
@@ -34,9 +32,6 @@
 key 0x121    BUTTON_THUMBL
 key 0x122    BUTTON_THUMBR
 
-# PS key
-key 0x2d0    BUTTON_MODE
-
 # Left Analog Stick
 axis 0x00    X
 axis 0x01    Y
@@ -74,3 +69,11 @@
 
 # Square
 # axis 0x37
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x120    BUTTON_SELECT
+# Start
+key 0x123    BUTTON_START
+# PS key
+key 0x2d0    BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl
new file mode 100644
index 0000000..3d93f0f
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl
@@ -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.
+
+#
+# Sony Playstation(R)3 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.12
+#   and when connected over Bluetooth
+#
+
+key 0x220   DPAD_UP
+key 0x223   DPAD_RIGHT
+key 0x221   DPAD_DOWN
+key 0x222   DPAD_LEFT
+
+key 0x130   BUTTON_A
+key 0x131   BUTTON_B
+key 0x134   BUTTON_X
+key 0x133   BUTTON_Y
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+key 0x13d   BUTTON_THUMBL
+key 0x13e   BUTTON_THUMBR
+
+# left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# L2 trigger
+axis 0x02   LTRIGGER
+
+# R2 trigger
+axis 0x05   RTRIGGER
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x13a   BUTTON_SELECT
+# Start
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl
new file mode 100644
index 0000000..3d93f0f
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl
@@ -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.
+
+#
+# Sony Playstation(R)3 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.12
+#   and when connected over Bluetooth
+#
+
+key 0x220   DPAD_UP
+key 0x223   DPAD_RIGHT
+key 0x221   DPAD_DOWN
+key 0x222   DPAD_LEFT
+
+key 0x130   BUTTON_A
+key 0x131   BUTTON_B
+key 0x134   BUTTON_X
+key 0x133   BUTTON_Y
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+key 0x13d   BUTTON_THUMBL
+key 0x13e   BUTTON_THUMBR
+
+# left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# L2 trigger
+axis 0x02   LTRIGGER
+
+# R2 trigger
+axis 0x05   RTRIGGER
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x13a   BUTTON_SELECT
+# Start
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl
new file mode 100644
index 0000000..5fe35f7
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl
@@ -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.
+
+#
+# Sony Playstation(R)3 Controller
+# - Version 0x8111 is for Linux hid-sony driver >=4.12 and when
+#   connected over USB
+#
+
+key 0x220   DPAD_UP
+key 0x223   DPAD_RIGHT
+key 0x221   DPAD_DOWN
+key 0x222   DPAD_LEFT
+
+key 0x130   BUTTON_A
+key 0x131   BUTTON_B
+key 0x134   BUTTON_X
+key 0x133   BUTTON_Y
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+key 0x13d   BUTTON_THUMBL
+key 0x13e   BUTTON_THUMBR
+
+# left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# L2 trigger
+axis 0x02   LTRIGGER
+
+# R2 trigger
+axis 0x05   RTRIGGER
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x13a   BUTTON_SELECT
+# Start
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_05c4.kl b/data/keyboards/Vendor_054c_Product_05c4.kl
index a1284a4..cd7ab1f 100644
--- a/data/keyboards/Vendor_054c_Product_05c4.kl
+++ b/data/keyboards/Vendor_054c_Product_05c4.kl
@@ -60,7 +60,6 @@
 key 0x138    BUTTON_SELECT
 # Options
 key 0x139    BUTTON_START
-
 # PS key
 key 0x13c    BUTTON_MODE
 
diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl
@@ -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.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+#   and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl
@@ -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.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+#   and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl
new file mode 100644
index 0000000..d38bdec
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl
@@ -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.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8111 is for Linux hid-sony driver >=4.10 and when
+#   connected over USB
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_09cc.kl b/data/keyboards/Vendor_054c_Product_09cc.kl
index a1284a4..cd7ab1f 100644
--- a/data/keyboards/Vendor_054c_Product_09cc.kl
+++ b/data/keyboards/Vendor_054c_Product_09cc.kl
@@ -60,7 +60,6 @@
 key 0x138    BUTTON_SELECT
 # Options
 key 0x139    BUTTON_START
-
 # PS key
 key 0x13c    BUTTON_MODE
 
diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl
@@ -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.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+#   and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl
@@ -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.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+#   and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl
new file mode 100644
index 0000000..d38bdec
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl
@@ -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.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8111 is for Linux hid-sony driver >=4.10 and when
+#   connected over USB
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_0ba0.kl b/data/keyboards/Vendor_054c_Product_0ba0.kl
new file mode 100644
index 0000000..bc6fc3b
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ba0.kl
@@ -0,0 +1,70 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 USB Dongle
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x130    BUTTON_X
+# Cross
+key 0x131    BUTTON_A
+# Circle
+key 0x132    BUTTON_B
+# Triangle
+key 0x133    BUTTON_Y
+
+key 0x134    BUTTON_L1
+key 0x135    BUTTON_R1
+key 0x136    BUTTON_L2
+key 0x137    BUTTON_R2
+
+# L2 axis
+axis 0x03   LTRIGGER
+# R2 axis
+axis 0x04   RTRIGGER
+
+
+# Left Analog Stick
+axis 0x00    X
+axis 0x01    Y
+# Right Analog Stick
+axis 0x02    Z
+axis 0x05    RZ
+
+# Left stick click
+key 0x13a    BUTTON_THUMBL
+# Right stick click
+key 0x13b    BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x138    BUTTON_SELECT
+# Options
+key 0x139    BUTTON_START
+# PS key
+key 0x13c    BUTTON_MODE
+
+# Touchpad press
+# The touchpad for this joystick will become a separate input device in future releases
+# and this button will be equivalent to left mouse button
+# Therefore, map it to KEYCODE_BUTTON_1 here to allow apps to still handle this on earlier versions
+key 0x13d   BUTTON_1
diff --git a/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl b/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl
new file mode 100644
index 0000000..8b85a38
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl
@@ -0,0 +1,67 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 USB Dongle
+# - Version 0x8111 is for Linux hid-sony driver >=4.10
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134   BUTTON_X
+# Cross
+key 0x130   BUTTON_A
+# Circle
+key 0x131   BUTTON_B
+# Triangle
+key 0x133   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+key 0x138   BUTTON_L2
+key 0x139   BUTTON_R2
+
+# L2 axis
+axis 0x02   LTRIGGER
+# R2 axis
+axis 0x05   RTRIGGER
+
+# Left Analog Stick
+axis 0x00   X
+axis 0x01   Y
+# Right Analog Stick
+axis 0x03   Z
+axis 0x04   RZ
+
+# Left stick click
+key 0x13d   BUTTON_THUMBL
+# Right stick click
+key 0x13e   BUTTON_THUMBR
+
+# Hat
+axis 0x10   HAT_X
+axis 0x11   HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a   BUTTON_SELECT
+# Options
+key 0x13b   BUTTON_START
+# PS key
+key 0x13c   BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index 53e9826..0885a05 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -28,11 +28,10 @@
 import android.text.SpannableString;
 import android.text.SpannedString;
 import android.text.TextUtils;
-import android.view.RecordingCanvas;
 
 /**
  * This class is a base class for Canvas's drawing operations. Any modifications here
- * should be accompanied by a similar modification to {@link RecordingCanvas}.
+ * should be accompanied by a similar modification to {@link BaseRecordingCanvas}.
  *
  * The purpose of this class is to minimize the cost of deciding between regular JNI
  * and @FastNative JNI to just the virtual call that Canvas already has.
@@ -377,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) |
@@ -632,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
new file mode 100644
index 0000000..fb30ca2
--- /dev/null
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -0,0 +1,674 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.Size;
+import android.text.GraphicsOperations;
+import android.text.MeasuredParagraph;
+import android.text.PrecomputedText;
+import android.text.SpannableString;
+import android.text.SpannedString;
+import android.text.TextUtils;
+
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * This class is a base class for canvases that defer drawing operations, so all
+ * the draw operations can be marked @FastNative. It contains a re-implementation of
+ * all the methods in {@link BaseCanvas}.
+ *
+ * @hide
+ */
+public class BaseRecordingCanvas extends Canvas {
+
+    public BaseRecordingCanvas(long nativeCanvas) {
+        super(nativeCanvas);
+    }
+
+    @Override
+    public final void drawArc(float left, float top, float right, float bottom, float startAngle,
+            float sweepAngle, boolean useCenter, @NonNull Paint paint) {
+        nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
+                useCenter, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle,
+            boolean useCenter, @NonNull Paint paint) {
+        drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
+                paint);
+    }
+
+    @Override
+    public final void drawARGB(int a, int r, int g, int b) {
+        drawColor(Color.argb(a, r, g, b));
+    }
+
+    @Override
+    public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top,
+            @Nullable Paint paint) {
+        throwIfCannotDraw(bitmap);
+        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
+                paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
+                bitmap.mDensity);
+    }
+
+    @Override
+    public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix,
+            @Nullable Paint paint) {
+        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
+                paint != null ? paint.getNativeInstance() : 0);
+    }
+
+    @Override
+    public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
+            @Nullable Paint paint) {
+        if (dst == null) {
+            throw new NullPointerException();
+        }
+        throwIfCannotDraw(bitmap);
+        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
+
+        int left, top, right, bottom;
+        if (src == null) {
+            left = top = 0;
+            right = bitmap.getWidth();
+            bottom = bitmap.getHeight();
+        } else {
+            left = src.left;
+            right = src.right;
+            top = src.top;
+            bottom = src.bottom;
+        }
+
+        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
+                bitmap.mDensity);
+    }
+
+    @Override
+    public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
+            @Nullable Paint paint) {
+        if (dst == null) {
+            throw new NullPointerException();
+        }
+        throwIfCannotDraw(bitmap);
+        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
+
+        float left, top, right, bottom;
+        if (src == null) {
+            left = top = 0;
+            right = bitmap.getWidth();
+            bottom = bitmap.getHeight();
+        } else {
+            left = src.left;
+            right = src.right;
+            top = src.top;
+            bottom = src.bottom;
+        }
+
+        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
+                bitmap.mDensity);
+    }
+
+    /** @deprecated checkstyle */
+    @Override
+    @Deprecated
+    public final void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y,
+            int width, int height, boolean hasAlpha, @Nullable Paint paint) {
+        // check for valid input
+        if (width < 0) {
+            throw new IllegalArgumentException("width must be >= 0");
+        }
+        if (height < 0) {
+            throw new IllegalArgumentException("height must be >= 0");
+        }
+        if (Math.abs(stride) < width) {
+            throw new IllegalArgumentException("abs(stride) must be >= width");
+        }
+        int lastScanline = offset + (height - 1) * stride;
+        int length = colors.length;
+        if (offset < 0 || (offset + width > length) || lastScanline < 0
+                || (lastScanline + width > length)) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        // quick escape if there's nothing to draw
+        if (width == 0 || height == 0) {
+            return;
+        }
+        // punch down to native for the actual draw
+        nDrawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
+                paint != null ? paint.getNativeInstance() : 0);
+    }
+
+    /** @deprecated checkstyle */
+    @Override
+    @Deprecated
+    public final void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y,
+            int width, int height, boolean hasAlpha, @Nullable Paint paint) {
+        // call through to the common float version
+        drawBitmap(colors, offset, stride, (float) x, (float) y, width, height,
+                hasAlpha, paint);
+    }
+
+    @Override
+    public final void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight,
+            @NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset,
+            @Nullable Paint paint) {
+        if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        if (meshWidth == 0 || meshHeight == 0) {
+            return;
+        }
+        int count = (meshWidth + 1) * (meshHeight + 1);
+        // we mul by 2 since we need two floats per vertex
+        checkRange(verts.length, vertOffset, count * 2);
+        if (colors != null) {
+            // no mul by 2, since we need only 1 color per vertex
+            checkRange(colors.length, colorOffset, count);
+        }
+        nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
+                verts, vertOffset, colors, colorOffset,
+                paint != null ? paint.getNativeInstance() : 0);
+    }
+
+    @Override
+    public final void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
+        nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawColor(@ColorInt int color) {
+        nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+    }
+
+    @Override
+    public final void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
+        nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt);
+    }
+
+    @Override
+    public final void drawLine(float startX, float startY, float stopX, float stopY,
+            @NonNull Paint paint) {
+        nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
+            @NonNull Paint paint) {
+        nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
+        drawLines(pts, 0, pts.length, paint);
+    }
+
+    @Override
+    public final void drawOval(float left, float top, float right, float bottom,
+            @NonNull Paint paint) {
+        nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
+        if (oval == null) {
+            throw new NullPointerException();
+        }
+        drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
+    }
+
+    @Override
+    public final void drawPaint(@NonNull Paint paint) {
+        nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst,
+            @Nullable Paint paint) {
+        Bitmap bitmap = patch.getBitmap();
+        throwIfCannotDraw(bitmap);
+        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
+        nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint,
+                mDensity, patch.getDensity());
+    }
+
+    @Override
+    public final void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst,
+            @Nullable Paint paint) {
+        Bitmap bitmap = patch.getBitmap();
+        throwIfCannotDraw(bitmap);
+        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
+        nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint,
+                mDensity, patch.getDensity());
+    }
+
+    @Override
+    public final void drawPath(@NonNull Path path, @NonNull Paint paint) {
+        if (path.isSimplePath && path.rects != null) {
+            nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
+        } else {
+            nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance());
+        }
+    }
+
+    @Override
+    public final void drawPicture(@NonNull Picture picture) {
+        picture.endRecording();
+        int restoreCount = save();
+        picture.draw(this);
+        restoreToCount(restoreCount);
+    }
+
+    @Override
+    public final void drawPicture(@NonNull Picture picture, @NonNull Rect dst) {
+        save();
+        translate(dst.left, dst.top);
+        if (picture.getWidth() > 0 && picture.getHeight() > 0) {
+            scale((float) dst.width() / picture.getWidth(),
+                    (float) dst.height() / picture.getHeight());
+        }
+        drawPicture(picture);
+        restore();
+    }
+
+    @Override
+    public final void drawPicture(@NonNull Picture picture, @NonNull RectF dst) {
+        save();
+        translate(dst.left, dst.top);
+        if (picture.getWidth() > 0 && picture.getHeight() > 0) {
+            scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
+        }
+        drawPicture(picture);
+        restore();
+    }
+
+    @Override
+    public final void drawPoint(float x, float y, @NonNull Paint paint) {
+        nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
+            @NonNull Paint paint) {
+        nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
+        drawPoints(pts, 0, pts.length, paint);
+    }
+
+    /** @deprecated checkstyle */
+    @Override
+    @Deprecated
+    public final void drawPosText(@NonNull char[] text, int index, int count,
+            @NonNull @Size(multiple = 2) float[] pos,
+            @NonNull Paint paint) {
+        if (index < 0 || index + count > text.length || count * 2 > pos.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        for (int i = 0; i < count; i++) {
+            drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
+        }
+    }
+
+    /** @deprecated checkstyle */
+    @Override
+    @Deprecated
+    public final void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
+            @NonNull Paint paint) {
+        drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
+    }
+
+    @Override
+    public final void drawRect(float left, float top, float right, float bottom,
+            @NonNull Paint paint) {
+        nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawRect(@NonNull Rect r, @NonNull Paint paint) {
+        drawRect(r.left, r.top, r.right, r.bottom, paint);
+    }
+
+    @Override
+    public final void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
+        nDrawRect(mNativeCanvasWrapper,
+                rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawRGB(int r, int g, int b) {
+        drawColor(Color.rgb(r, g, b));
+    }
+
+    @Override
+    public final void drawRoundRect(float left, float top, float right, float bottom,
+            float rx, float ry, @NonNull Paint paint) {
+        nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
+                paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
+        drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
+    }
+
+    @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)
+                | (text.length - index - count)) < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
+                paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
+            @NonNull Paint paint) {
+        if ((start | end | (end - start) | (text.length() - end)) < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (text instanceof String || text instanceof SpannedString
+                || text instanceof SpannableString) {
+            nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
+                    paint.mBidiFlags, paint.getNativeInstance());
+        } else if (text instanceof GraphicsOperations) {
+            ((GraphicsOperations) text).drawText(this, start, end, x, y,
+                    paint);
+        } else {
+            char[] buf = TemporaryBuffer.obtain(end - start);
+            TextUtils.getChars(text, start, end, buf, 0);
+            nDrawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
+                    paint.mBidiFlags, paint.getNativeInstance());
+            TemporaryBuffer.recycle(buf);
+        }
+    }
+
+    @Override
+    public final void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
+        nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
+                paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawText(@NonNull String text, int start, int end, float x, float y,
+            @NonNull Paint paint) {
+        if ((start | end | (end - start) | (text.length() - end)) < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
+                paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
+            float hOffset, float vOffset, @NonNull Paint paint) {
+        if (index < 0 || index + count > text.length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
+                path.readOnlyNI(), hOffset, vOffset,
+                paint.mBidiFlags, paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
+            float vOffset, @NonNull Paint paint) {
+        if (text.length() > 0) {
+            nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
+                    paint.mBidiFlags, paint.getNativeInstance());
+        }
+    }
+
+    @Override
+    public final void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
+            int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
+
+        if (text == null) {
+            throw new NullPointerException("text is null");
+        }
+        if (paint == null) {
+            throw new NullPointerException("paint is null");
+        }
+        if ((index | count | contextIndex | contextCount | index - contextIndex
+                | (contextIndex + contextCount) - (index + count)
+                | text.length - (contextIndex + contextCount)) < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
+                x, y, isRtl, paint.getNativeInstance(), 0 /* measured text */);
+    }
+
+    @Override
+    public final void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
+            int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
+
+        if (text == null) {
+            throw new NullPointerException("text is null");
+        }
+        if (paint == null) {
+            throw new NullPointerException("paint is null");
+        }
+        if ((start | end | contextStart | contextEnd | start - contextStart | end - start
+                | contextEnd - end | text.length() - contextEnd) < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (text instanceof String || text instanceof SpannedString
+                || text instanceof SpannableString) {
+            nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
+                    contextEnd, x, y, isRtl, paint.getNativeInstance());
+        } else if (text instanceof GraphicsOperations) {
+            ((GraphicsOperations) text).drawTextRun(this, start, end,
+                    contextStart, contextEnd, x, y, isRtl, paint);
+        } else {
+            if (text instanceof PrecomputedText) {
+                final PrecomputedText pt = (PrecomputedText) text;
+                final int paraIndex = pt.findParaIndex(start);
+                if (end <= pt.getParagraphEnd(paraIndex)) {
+                    final int paraStart = pt.getParagraphStart(paraIndex);
+                    final MeasuredParagraph mp = pt.getMeasuredParagraph(paraIndex);
+                    // Only support if the target is in the same paragraph.
+                    nDrawTextRun(mNativeCanvasWrapper,
+                            mp.getChars(),
+                            start - paraStart,
+                            end - start,
+                            contextStart - paraStart,
+                            contextEnd - contextStart,
+                            x, y, isRtl, paint.getNativeInstance(),
+                            mp.getNativeMeasuredParagraph().getNativePtr());
+                    return;
+                }
+            }
+            int contextLen = contextEnd - contextStart;
+            int len = end - start;
+            char[] buf = TemporaryBuffer.obtain(contextLen);
+            TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
+            nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
+                    0, contextLen, x, y, isRtl, paint.getNativeInstance(),
+                    0 /* measured paragraph pointer */);
+            TemporaryBuffer.recycle(buf);
+        }
+    }
+
+    @Override
+    public final void drawVertices(@NonNull VertexMode mode, int vertexCount,
+            @NonNull float[] verts, int vertOffset, @Nullable float[] texs, int texOffset,
+            @Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset,
+            int indexCount, @NonNull Paint paint) {
+        checkRange(verts.length, vertOffset, vertexCount);
+        if (texs != null) {
+            checkRange(texs.length, texOffset, vertexCount);
+        }
+        if (colors != null) {
+            checkRange(colors.length, colorOffset, vertexCount / 2);
+        }
+        if (indices != null) {
+            checkRange(indices.length, indexOffset, indexCount);
+        }
+        nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
+                vertOffset, texs, texOffset, colors, colorOffset,
+                indices, indexOffset, indexCount, paint.getNativeInstance());
+    }
+
+    @FastNative
+    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
+            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
+
+    @FastNative
+    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap,
+            float srcLeft, float srcTop, float srcRight, float srcBottom,
+            float dstLeft, float dstTop, float dstRight, float dstBottom,
+            long nativePaintOrZero, int screenDensity, int bitmapDensity);
+
+    @FastNative
+    private static native void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
+            float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero);
+
+    @FastNative
+    private static native void nDrawColor(long nativeCanvas, int color, int mode);
+
+    @FastNative
+    private static native void nDrawPaint(long nativeCanvas, long nativePaint);
+
+    @FastNative
+    private static native void nDrawPoint(long canvasHandle, float x, float y, long paintHandle);
+
+    @FastNative
+    private static native void nDrawPoints(long canvasHandle, float[] pts, int offset, int count,
+            long paintHandle);
+
+    @FastNative
+    private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX,
+            float stopY, long nativePaint);
+
+    @FastNative
+    private static native void nDrawLines(long canvasHandle, float[] pts, int offset, int count,
+            long paintHandle);
+
+    @FastNative
+    private static native void nDrawRect(long nativeCanvas, float left, float top, float right,
+            float bottom, long nativePaint);
+
+    @FastNative
+    private static native void nDrawOval(long nativeCanvas, float left, float top, float right,
+            float bottom, long nativePaint);
+
+    @FastNative
+    private static native void nDrawCircle(long nativeCanvas, float cx, float cy, float radius,
+            long nativePaint);
+
+    @FastNative
+    private static native void nDrawArc(long nativeCanvas, float left, float top, float right,
+            float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint);
+
+    @FastNative
+    private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right,
+            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
+    private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint);
+
+    @FastNative
+    private static native void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
+            float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
+            int screenDensity, int bitmapDensity);
+
+    @FastNative
+    private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
+            long nativeMatrix, long nativePaint);
+
+    @FastNative
+    private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
+            int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
+            long nativePaint);
+
+    @FastNative
+    private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts,
+            int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
+            short[] indices, int indexOffset, int indexCount, long nativePaint);
+
+    @FastNative
+    private static native void nDrawText(long nativeCanvas, char[] text, int index, int count,
+            float x, float y, int flags, long nativePaint);
+
+    @FastNative
+    private static native void nDrawText(long nativeCanvas, String text, int start, int end,
+            float x, float y, int flags, long nativePaint);
+
+    @FastNative
+    private static native void nDrawTextRun(long nativeCanvas, String text, int start, int end,
+            int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint);
+
+    @FastNative
+    private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
+            int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
+            long nativePrecomputedText);
+
+    @FastNative
+    private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
+            long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint);
+
+    @FastNative
+    private static native void nDrawTextOnPath(long nativeCanvas, String text, long nativePath,
+            float hOffset, float vOffset, int flags, long nativePaint);
+}
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index cea6c1c..1cd756f 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -24,6 +24,7 @@
 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;
@@ -724,6 +725,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,6 +1296,7 @@
             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);
             if (source.getWidth() != width || source.getHeight() != height) {
                 canvas.scale(width / (float) source.getWidth(),
@@ -2117,6 +2161,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/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 82435d5..21cc375 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -40,17 +40,25 @@
     /* Parse fallback list (no names) */
     @UnsupportedAppUsage
     public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
+        return parse(in, "/system/fonts");
+    }
+
+    /**
+     * Parse the fonts.xml
+     */
+    public static FontConfig parse(InputStream in, String fontDir)
+            throws XmlPullParserException, IOException {
         try {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(in, null);
             parser.nextTag();
-            return readFamilies(parser);
+            return readFamilies(parser, fontDir);
         } finally {
             in.close();
         }
     }
 
-    private static FontConfig readFamilies(XmlPullParser parser)
+    private static FontConfig readFamilies(XmlPullParser parser, String fontDir)
             throws XmlPullParserException, IOException {
         List<FontConfig.Family> families = new ArrayList<>();
         List<FontConfig.Alias> aliases = new ArrayList<>();
@@ -60,7 +68,7 @@
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             String tag = parser.getName();
             if (tag.equals("family")) {
-                families.add(readFamily(parser));
+                families.add(readFamily(parser, fontDir));
             } else if (tag.equals("alias")) {
                 aliases.add(readAlias(parser));
             } else {
@@ -71,7 +79,10 @@
                 aliases.toArray(new FontConfig.Alias[aliases.size()]));
     }
 
-    private static FontConfig.Family readFamily(XmlPullParser parser)
+    /**
+     * Reads a family element
+     */
+    public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir)
             throws XmlPullParserException, IOException {
         final String name = parser.getAttributeValue(null, "name");
         final String lang = parser.getAttributeValue("", "lang");
@@ -81,7 +92,7 @@
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             final String tag = parser.getName();
             if (tag.equals("font")) {
-                fonts.add(readFont(parser));
+                fonts.add(readFont(parser, fontDir));
             } else {
                 skip(parser);
             }
@@ -102,7 +113,7 @@
     private static final Pattern FILENAME_WHITESPACE_PATTERN =
             Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
 
-    private static FontConfig.Font readFont(XmlPullParser parser)
+    private static FontConfig.Font readFont(XmlPullParser parser, String fontDir)
             throws XmlPullParserException, IOException {
         String indexStr = parser.getAttributeValue(null, "index");
         int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
@@ -125,7 +136,7 @@
             }
         }
         String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
-        return new FontConfig.Font(sanitizedName, index, axes.toArray(
+        return new FontConfig.Font(fontDir + sanitizedName, index, axes.toArray(
                 new FontVariationAxis[axes.size()]), weight, isItalic, fallbackFor);
     }
 
@@ -137,7 +148,10 @@
         return new FontVariationAxis(tagStr, Float.parseFloat(styleValueStr));
     }
 
-    private static FontConfig.Alias readAlias(XmlPullParser parser)
+    /**
+     * Reads alias elements
+     */
+    public static FontConfig.Alias readAlias(XmlPullParser parser)
             throws XmlPullParserException, IOException {
         String name = parser.getAttributeValue(null, "name");
         String toName = parser.getAttributeValue(null, "to");
@@ -152,7 +166,10 @@
         return new FontConfig.Alias(name, toName, weight);
     }
 
-    private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
+    /**
+     * Skip until next element
+     */
+    public static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
         int depth = 1;
         while (depth > 0) {
             switch (parser.next()) {
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 7bed1ac..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;
 
 /**
@@ -187,7 +188,7 @@
      *  {@link OnHeaderDecodedListener OnHeaderDecodedListener} and once with an
      *  implementation of {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}
      *  that calls {@link #setTargetSize} with smaller dimensions. One {@code Source}
-     *  even used simultaneously in multiple threads.</p>
+     *  can even be used simultaneously in multiple threads.</p>
      */
     public static abstract class Source {
         private Source() {}
@@ -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/Paint.java b/graphics/java/android/graphics/Paint.java
index 85b39fe..69ff3bc 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -17,6 +17,7 @@
 package android.graphics;
 
 import android.annotation.ColorInt;
+import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,6 +38,8 @@
 
 import libcore.util.NativeAllocationRegistry;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -309,38 +312,47 @@
      */
     public static final int DIRECTION_RTL = 1;
 
+    /** @hide */
+    @IntDef(prefix = { "CURSOR_" }, value = {
+        CURSOR_AFTER, CURSOR_AT_OR_AFTER, CURSOR_BEFORE, CURSOR_AT_OR_BEFORE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CursorOption {}
+
     /**
-     * Option for getTextRunCursor to compute the valid cursor after
-     * offset or the limit of the context, whichever is less.
-     * @hide
+     * Option for getTextRunCursor.
+     *
+     * Compute the valid cursor after offset or the limit of the context, whichever is less.
      */
     public static final int CURSOR_AFTER = 0;
 
     /**
-     * Option for getTextRunCursor to compute the valid cursor at or after
-     * the offset or the limit of the context, whichever is less.
-     * @hide
+     * Option for getTextRunCursor.
+     *
+     * Compute the valid cursor at or after the offset or the limit of the context, whichever is
+     * less.
      */
     public static final int CURSOR_AT_OR_AFTER = 1;
 
      /**
-     * Option for getTextRunCursor to compute the valid cursor before
-     * offset or the start of the context, whichever is greater.
-     * @hide
+     * Option for getTextRunCursor.
+     *
+     * Compute the valid cursor before offset or the start of the context, whichever is greater.
      */
     public static final int CURSOR_BEFORE = 2;
 
    /**
-     * Option for getTextRunCursor to compute the valid cursor at or before
-     * offset or the start of the context, whichever is greater.
-     * @hide
+     * Option for getTextRunCursor.
+     *
+     * Compute the valid cursor at or before offset or the start of the context, whichever is
+     * greater.
      */
     public static final int CURSOR_AT_OR_BEFORE = 3;
 
     /**
-     * Option for getTextRunCursor to return offset if the cursor at offset
-     * is valid, or -1 if it isn't.
-     * @hide
+     * Option for getTextRunCursor.
+     *
+     * Return offset if the cursor at offset is valid, or -1 if it isn't.
      */
     public static final int CURSOR_AT = 4;
 
@@ -580,49 +592,6 @@
         mShadowLayerColor = paint.mShadowLayerColor;
     }
 
-    /**
-     * Returns true if all attributes are equal.
-     *
-     * The caller is expected to have checked the trivial cases, like the pointers being equal,
-     * the objects having different classes, or the parameter being null.
-     * @hide
-     */
-    public boolean hasEqualAttributes(@NonNull Paint other) {
-        return mColorFilter == other.mColorFilter
-                && mMaskFilter == other.mMaskFilter
-                && mPathEffect == other.mPathEffect
-                && mShader == other.mShader
-                && mTypeface == other.mTypeface
-                && mXfermode == other.mXfermode
-                && mHasCompatScaling == other.mHasCompatScaling
-                && mCompatScaling == other.mCompatScaling
-                && mInvCompatScaling == other.mInvCompatScaling
-                && mBidiFlags == other.mBidiFlags
-                && mLocales.equals(other.mLocales)
-                && TextUtils.equals(mFontFeatureSettings, other.mFontFeatureSettings)
-                && TextUtils.equals(mFontVariationSettings, other.mFontVariationSettings)
-                && mShadowLayerRadius == other.mShadowLayerRadius
-                && mShadowLayerDx == other.mShadowLayerDx
-                && mShadowLayerDy == other.mShadowLayerDy
-                && mShadowLayerColor == other.mShadowLayerColor
-                && getFlags() == other.getFlags()
-                && getHinting() == other.getHinting()
-                && getStyle() == other.getStyle()
-                && getColor() == other.getColor()
-                && getStrokeWidth() == other.getStrokeWidth()
-                && getStrokeMiter() == other.getStrokeMiter()
-                && getStrokeCap() == other.getStrokeCap()
-                && getStrokeJoin() == other.getStrokeJoin()
-                && getTextAlign() == other.getTextAlign()
-                && isElegantTextHeight() == other.isElegantTextHeight()
-                && getTextSize() == other.getTextSize()
-                && getTextScaleX() == other.getTextScaleX()
-                && getTextSkewX() == other.getTextSkewX()
-                && getLetterSpacing() == other.getLetterSpacing()
-                && getWordSpacing() == other.getWordSpacing()
-                && getHyphenEdit() == other.getHyphenEdit();
-    }
-
     /** @hide */
     @UnsupportedAppUsage
     public void setCompatibilityScaling(float factor) {
@@ -1383,6 +1352,38 @@
     }
 
     /**
+     * Returns the blur radius of the shadow layer.
+     * @see #setShadowLayer(float,float,float,int)
+     */
+    public float getShadowLayerRadius() {
+        return mShadowLayerRadius;
+    }
+
+    /**
+     * Returns the x offset of the shadow layer.
+     * @see #setShadowLayer(float,float,float,int)
+     */
+    public float getShadowLayerDx() {
+        return mShadowLayerDx;
+    }
+
+    /**
+     * Returns the y offset of the shadow layer.
+     * @see #setShadowLayer(float,float,float,int)
+     */
+    public float getShadowLayerDy() {
+        return mShadowLayerDy;
+    }
+
+    /**
+     * Returns the color of the shadow layer.
+     * @see #setShadowLayer(float,float,float,int)
+     */
+    public @ColorInt int getShadowLayerColor() {
+        return mShadowLayerColor;
+    }
+
+    /**
      * Return the paint's Align value for drawing text. This controls how the
      * text is positioned relative to its origin. LEFT align means that all of
      * the text will be drawn to the right of its origin (i.e. the origin
@@ -2410,34 +2411,32 @@
     }
 
     /**
-     * Returns the next cursor position in the run.  This avoids placing the
-     * cursor between surrogates, between characters that form conjuncts,
-     * between base characters and combining marks, or within a reordering
-     * cluster.
+     * Returns the next cursor position in the run.
      *
-     * <p>ContextStart and offset are relative to the start of text.
-     * The context is the shaping context for cursor movement, generally
-     * the bounds of the metric span enclosing the cursor in the direction of
-     * movement.
+     * This avoids placing the cursor between surrogates, between characters that form conjuncts,
+     * between base characters and combining marks, or within a reordering cluster.
      *
-     * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid
-     * cursor position, this returns -1.  Otherwise this will never return a
-     * value before contextStart or after contextStart + contextLength.
+     * <p>
+     * ContextStart and offset are relative to the start of text.
+     * The context is the shaping context for cursor movement, generally the bounds of the metric
+     * span enclosing the cursor in the direction of movement.
+     *
+     * <p>
+     * If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid cursor position, this
+     * returns -1.  Otherwise this will never return a value before contextStart or after
+     * contextStart + contextLength.
      *
      * @param text the text
      * @param contextStart the start of the context
      * @param contextLength the length of the context
-     * @param dir either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR}
+     * @param isRtl true if the paragraph context is RTL, otherwise false
      * @param offset the cursor position to move from
-     * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER},
-     * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE},
-     * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT}
+     * @param cursorOpt how to move the cursor
      * @return the offset of the next position, or -1
-     * @hide
      */
-    @UnsupportedAppUsage
-    public int getTextRunCursor(char[] text, int contextStart, int contextLength,
-            int dir, int offset, int cursorOpt) {
+    public int getTextRunCursor(@NonNull char[] text, @IntRange(from = 0) int contextStart,
+            @IntRange(from = 0) int contextLength, boolean isRtl, @IntRange(from = 0) int offset,
+            @CursorOption int cursorOpt) {
         int contextEnd = contextStart + contextLength;
         if (((contextStart | contextEnd | offset | (contextEnd - contextStart)
                 | (offset - contextStart) | (contextEnd - offset)
@@ -2446,85 +2445,87 @@
             throw new IndexOutOfBoundsException();
         }
 
-        return nGetTextRunCursor(mNativePaint, text, contextStart, contextLength, dir, offset,
-                cursorOpt);
+        return nGetTextRunCursor(mNativePaint, text, contextStart, contextLength,
+                isRtl ? DIRECTION_RTL : DIRECTION_LTR, offset, cursorOpt);
     }
 
     /**
-     * Returns the next cursor position in the run.  This avoids placing the
-     * cursor between surrogates, between characters that form conjuncts,
-     * between base characters and combining marks, or within a reordering
-     * cluster.
+     * Returns the next cursor position in the run.
      *
-     * <p>ContextStart, contextEnd, and offset are relative to the start of
+     * This avoids placing the cursor between surrogates, between characters that form conjuncts,
+     * between base characters and combining marks, or within a reordering cluster.
+     *
+     * <p>
+     * ContextStart, contextEnd, and offset are relative to the start of
      * text.  The context is the shaping context for cursor movement, generally
      * the bounds of the metric span enclosing the cursor in the direction of
      * movement.
      *
-     * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid
-     * cursor position, this returns -1.  Otherwise this will never return a
-     * value before contextStart or after contextEnd.
+     * <p>
+     * If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid cursor position, this
+     * returns -1.  Otherwise this will never return a value before contextStart or after
+     * contextEnd.
      *
      * @param text the text
      * @param contextStart the start of the context
      * @param contextEnd the end of the context
-     * @param dir either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR}
+     * @param isRtl true if the paragraph context is RTL, otherwise false
      * @param offset the cursor position to move from
-     * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER},
-     * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE},
-     * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT}
+     * @param cursorOpt how to move the cursor
      * @return the offset of the next position, or -1
-     * @hide
      */
-    public int getTextRunCursor(CharSequence text, int contextStart,
-           int contextEnd, int dir, int offset, int cursorOpt) {
+    public int getTextRunCursor(@NonNull CharSequence text, @IntRange(from = 0) int contextStart,
+            @IntRange(from = 0) int contextEnd, boolean isRtl, @IntRange(from = 0) int offset,
+            @CursorOption int cursorOpt) {
 
         if (text instanceof String || text instanceof SpannedString ||
                 text instanceof SpannableString) {
             return getTextRunCursor(text.toString(), contextStart, contextEnd,
-                    dir, offset, cursorOpt);
+                    isRtl, offset, cursorOpt);
         }
         if (text instanceof GraphicsOperations) {
             return ((GraphicsOperations) text).getTextRunCursor(
-                    contextStart, contextEnd, dir, offset, cursorOpt, this);
+                    contextStart, contextEnd, isRtl, offset, cursorOpt, this);
         }
 
         int contextLen = contextEnd - contextStart;
         char[] buf = TemporaryBuffer.obtain(contextLen);
         TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
-        int relPos = getTextRunCursor(buf, 0, contextLen, dir, offset - contextStart, cursorOpt);
+        int relPos = getTextRunCursor(buf, 0, contextLen, isRtl, offset - contextStart, cursorOpt);
         TemporaryBuffer.recycle(buf);
         return (relPos == -1) ? -1 : relPos + contextStart;
     }
 
     /**
-     * Returns the next cursor position in the run.  This avoids placing the
-     * cursor between surrogates, between characters that form conjuncts,
-     * between base characters and combining marks, or within a reordering
-     * cluster.
+     * Returns the next cursor position in the run.
      *
-     * <p>ContextStart, contextEnd, and offset are relative to the start of
-     * text.  The context is the shaping context for cursor movement, generally
-     * the bounds of the metric span enclosing the cursor in the direction of
-     * movement.
+     * This avoids placing the cursor between surrogates, between characters that form conjuncts,
+     * between base characters and combining marks, or within a reordering cluster.
      *
-     * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid
-     * cursor position, this returns -1.  Otherwise this will never return a
-     * value before contextStart or after contextEnd.
+     * <p>
+     * ContextStart, contextEnd, and offset are relative to the start of text.  The context is the
+     * shaping context for cursor movement, generally the bounds of the metric span enclosing the
+     * cursor in the direction of movement.
+     * </p>
+     *
+     * <p>
+     * If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid cursor position, this
+     * returns -1.  Otherwise this will never return a value before contextStart or after
+     * contextEnd.
+     * </p>
      *
      * @param text the text
      * @param contextStart the start of the context
      * @param contextEnd the end of the context
-     * @param dir either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR}
+     * @param isRtl true if the paragraph context is RTL, otherwise false.
      * @param offset the cursor position to move from
-     * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER},
-     * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE},
-     * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT}
+     * @param cursorOpt how to move the cursor
      * @return the offset of the next position, or -1
      * @hide
      */
-    public int getTextRunCursor(String text, int contextStart, int contextEnd,
-            int dir, int offset, int cursorOpt) {
+    public int getTextRunCursor(@NonNull String text, @IntRange(from = 0) int contextStart,
+            @IntRange(from = 0) int contextEnd, boolean isRtl, @IntRange(from = 0) int offset,
+            @CursorOption int cursorOpt) {
         if (((contextStart | contextEnd | offset | (contextEnd - contextStart)
                 | (offset - contextStart) | (contextEnd - offset)
                 | (text.length() - contextEnd) | cursorOpt) < 0)
@@ -2532,8 +2533,8 @@
             throw new IndexOutOfBoundsException();
         }
 
-        return nGetTextRunCursor(mNativePaint, text, contextStart, contextEnd, dir, offset,
-                cursorOpt);
+        return nGetTextRunCursor(mNativePaint, text, contextStart, contextEnd,
+                isRtl ? DIRECTION_RTL : DIRECTION_LTR, offset, cursorOpt);
     }
 
     /**
@@ -2599,11 +2600,13 @@
      * Return in bounds (allocated by the caller) the smallest rectangle that
      * encloses all of the characters, with an implied origin at (0,0).
      *
+     * Note that styles are ignored even if you pass {@link android.text.Spanned} instance.
+     * Use {@link android.text.StaticLayout} for measuring bounds of {@link android.text.Spanned}.
+     *
      * @param text text to measure and return its bounds
      * @param start index of the first char in the text to measure
      * @param end 1 past the last char in the text to measure
      * @param bounds returns the unioned bounds of all the text. Must be allocated by the caller
-     * @hide
      */
     public void getTextBounds(CharSequence text, int start, int end, Rect bounds) {
         if ((start | end | (end - start) | (text.length() - end)) < 0) {
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 4fec33f..c4dc0ad 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -23,8 +23,11 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
+import android.util.proto.WireTypeMismatchException;
 
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -232,6 +235,40 @@
     }
 
     /**
+     * Read from a protocol buffer input stream.
+     * Protocol buffer message definition at {@link android.graphics.RectProto}
+     *
+     * @param proto     Stream to read the Rect object from.
+     * @param fieldId   Field Id of the Rect as defined in the parent message
+     * @hide
+     */
+    public void readFromProto(@NonNull ProtoInputStream proto, long fieldId) throws IOException,
+            WireTypeMismatchException {
+        final long token = proto.start(fieldId);
+        try {
+            while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                switch (proto.getFieldNumber()) {
+                    case (int) RectProto.LEFT:
+                        left = proto.readInt(RectProto.LEFT);
+                        break;
+                    case (int) RectProto.TOP:
+                        top = proto.readInt(RectProto.TOP);
+                        break;
+                    case (int) RectProto.RIGHT:
+                        right = proto.readInt(RectProto.RIGHT);
+                        break;
+                    case (int) RectProto.BOTTOM:
+                        bottom = proto.readInt(RectProto.BOTTOM);
+                        break;
+                }
+            }
+        } finally {
+            // Let caller handle any exceptions
+            proto.end(token);
+        }
+    }
+
+    /**
      * Returns true if the rectangle is empty (left >= right or top >= bottom)
      */
     public final boolean isEmpty() {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 492c236..7ad207f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -34,7 +34,6 @@
 import android.provider.FontRequest;
 import android.provider.FontsContract;
 import android.text.FontConfig;
-import android.util.ArrayMap;
 import android.util.Base64;
 import android.util.LongSparseArray;
 import android.util.LruCache;
@@ -1104,6 +1103,9 @@
         }
 
         for (FontConfig.Alias alias : aliases) {
+            if (systemFontMap.containsKey(alias.getName())) {
+                continue; // If alias and named family are conflict, use named family.
+            }
             final Typeface base = systemFontMap.get(alias.getToName());
             final int weight = alias.getWeight();
             final Typeface newFace = weight == 400 ? base :
@@ -1112,13 +1114,6 @@
         }
     }
 
-    // Following methods are left for layoutlib
-    // TODO: Remove once layoutlib stop calling buildSystemFallback
-    /** @hide */
-    public static void buildSystemFallback(String xmlPath, String fontDir,
-            ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
-    }
-
     static {
         final HashMap<String, Typeface> systemFontMap = new HashMap<>();
         initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(),
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 76f2cfb..6c1372f 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -51,6 +51,7 @@
 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;
@@ -1231,7 +1232,8 @@
     /**
      * @hide
      */
-    public static class VectorDrawableAnimatorRT implements VectorDrawableAnimator {
+    public static class VectorDrawableAnimatorRT implements VectorDrawableAnimator,
+            NativeVectorDrawableAnimator {
         private static final int START_ANIMATION = 1;
         private static final int REVERSE_ANIMATION = 2;
         private static final int RESET_ANIMATION = 3;
@@ -1704,6 +1706,7 @@
             }
         }
 
+        @Override
         public long getAnimatorNativePtr() {
             return mSetPtr;
         }
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 1458c66..bd1ac25 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -422,9 +422,10 @@
                     nAddAxis(builderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue());
                 }
             }
-            final long ptr = nBuild(builderPtr, mBuffer, mWeight, italic, mTtcIndex);
-            final Font font = new Font(ptr, mBuffer, mFile, mWeight, italic, mTtcIndex, mAxes,
-                    mLocaleList);
+            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);
             sFontRegistory.registerNativeAllocation(font, ptr);
             return font;
         }
@@ -477,7 +478,7 @@
     }
 
     /**
-     * Retuns a font file buffer.
+     * Returns a font file buffer.
      *
      * @return a font buffer
      */
diff --git a/graphics/java/android/graphics/fonts/FontCustomizationParser.java b/graphics/java/android/graphics/fonts/FontCustomizationParser.java
new file mode 100644
index 0000000..0291d74
--- /dev/null
+++ b/graphics/java/android/graphics/fonts/FontCustomizationParser.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.NonNull;
+import android.graphics.FontListParser;
+import android.text.FontConfig;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Parser for font customization
+ *
+ * @hide
+ */
+public class FontCustomizationParser {
+    /**
+     * Represents a customization XML
+     */
+    public static class Result {
+        ArrayList<FontConfig.Family> mAdditionalNamedFamilies = new ArrayList<>();
+        ArrayList<FontConfig.Alias> mAdditionalAliases = new ArrayList<>();
+    }
+
+    /**
+     * Parses the customization XML
+     *
+     * Caller must close the input stream
+     */
+    public static Result parse(@NonNull InputStream in, @NonNull String fontDir)
+            throws XmlPullParserException, IOException {
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(in, null);
+        parser.nextTag();
+        return readFamilies(parser, fontDir);
+    }
+
+    private static void validate(Result result) {
+        HashSet<String> familyNames = new HashSet<>();
+        for (int i = 0; i < result.mAdditionalNamedFamilies.size(); ++i) {
+            final FontConfig.Family family = result.mAdditionalNamedFamilies.get(i);
+            final String name = family.getName();
+            if (name == null) {
+                throw new IllegalArgumentException("new-named-family requires name attribute");
+            }
+            if (!familyNames.add(name)) {
+                throw new IllegalArgumentException(
+                        "new-named-family requires unique name attribute");
+            }
+        }
+    }
+
+    private static Result readFamilies(XmlPullParser parser, String fontDir)
+            throws XmlPullParserException, IOException {
+        Result out = new Result();
+        parser.require(XmlPullParser.START_TAG, null, "fonts-modification");
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
+            String tag = parser.getName();
+            if (tag.equals("family")) {
+                readFamily(parser, fontDir, out);
+            } else if (tag.equals("alias")) {
+                out.mAdditionalAliases.add(FontListParser.readAlias(parser));
+            } else {
+                FontListParser.skip(parser);
+            }
+        }
+        validate(out);
+        return out;
+    }
+
+    private static void readFamily(XmlPullParser parser, String fontDir, Result out)
+            throws XmlPullParserException, IOException {
+        final String customizationType = parser.getAttributeValue(null, "customizationType");
+        if (customizationType == null) {
+            throw new IllegalArgumentException("customizationType must be specified");
+        }
+        if (customizationType.equals("new-named-family")) {
+            out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir));
+        } else {
+            throw new IllegalArgumentException("Unknown customizationType=" + customizationType);
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index f4a2199..2d21bbb 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -45,7 +45,7 @@
 /**
  * Provides the system font configurations.
  */
-public class SystemFonts {
+public final class SystemFonts {
     private static final String TAG = "SystemFonts";
     private static final String DEFAULT_FAMILY = "sans-serif";
 
@@ -58,8 +58,7 @@
     /**
      * Returns all available font files in the system.
      *
-     * Note: The order of this font doesn't indicates anything.
-     * @return an array of system fonts
+     * @return a set of system fonts
      */
     public static @NonNull Set<Font> getAvailableFonts() {
         HashSet<Font> set = new HashSet<>();
@@ -114,7 +113,6 @@
     private static void pushFamilyToFallback(@NonNull FontConfig.Family xmlFamily,
             @NonNull ArrayMap<String, ArrayList<FontFamily>> fallbackMap,
             @NonNull Map<String, ByteBuffer> cache,
-            @NonNull String fontDir,
             @NonNull ArrayList<Font> availableFonts) {
 
         final String languageTags = xmlFamily.getLanguages();
@@ -139,8 +137,7 @@
         }
 
         final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily(
-                xmlFamily.getName(), defaultFonts, languageTags, variant, cache, fontDir,
-                availableFonts);
+                xmlFamily.getName(), defaultFonts, languageTags, variant, cache, availableFonts);
 
         // Insert family into fallback map.
         for (int i = 0; i < fallbackMap.size(); i++) {
@@ -152,7 +149,7 @@
                 }
             } else {
                 final FontFamily family = createFontFamily(
-                        xmlFamily.getName(), fallback, languageTags, variant, cache, fontDir,
+                        xmlFamily.getName(), fallback, languageTags, variant, cache,
                         availableFonts);
                 if (family != null) {
                     fallbackMap.valueAt(i).add(family);
@@ -170,7 +167,6 @@
             @NonNull String languageTags,
             @FontConfig.Family.Variant int variant,
             @NonNull Map<String, ByteBuffer> cache,
-            @NonNull String fontDir,
             @NonNull ArrayList<Font> availableFonts) {
         if (fonts.size() == 0) {
             return null;
@@ -179,7 +175,7 @@
         FontFamily.Builder b = null;
         for (int i = 0; i < fonts.size(); i++) {
             final FontConfig.Font fontConfig = fonts.get(i);
-            final String fullPath = fontDir + fontConfig.getFontName();
+            final String fullPath = fontConfig.getFontName();
             ByteBuffer buffer = cache.get(fullPath);
             if (buffer == null) {
                 if (cache.containsKey(fullPath)) {
@@ -214,6 +210,22 @@
         return b == null ? null : b.build(languageTags, variant);
     }
 
+    private static void appendNamedFamily(@NonNull FontConfig.Family xmlFamily,
+            @NonNull HashMap<String, ByteBuffer> bufferCache,
+            @NonNull ArrayMap<String, ArrayList<FontFamily>> fallbackListMap,
+            @NonNull ArrayList<Font> availableFonts) {
+        final String familyName = xmlFamily.getName();
+        final FontFamily family = createFontFamily(
+                familyName, Arrays.asList(xmlFamily.getFonts()),
+                xmlFamily.getLanguages(), xmlFamily.getVariant(), bufferCache, availableFonts);
+        if (family == null) {
+            return;
+        }
+        final ArrayList<FontFamily> fallback = new ArrayList<>();
+        fallback.add(family);
+        fallbackListMap.put(familyName, fallback);
+    }
+
     /**
      * Build the system fallback from xml file.
      *
@@ -227,11 +239,12 @@
     @VisibleForTesting
     public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath,
             @NonNull String fontDir,
+            @NonNull FontCustomizationParser.Result oemCustomization,
             @NonNull ArrayMap<String, FontFamily[]> fallbackMap,
             @NonNull ArrayList<Font> availableFonts) {
         try {
             final FileInputStream fontsIn = new FileInputStream(xmlPath);
-            final FontConfig fontConfig = FontListParser.parse(fontsIn);
+            final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir);
 
             final HashMap<String, ByteBuffer> bufferCache = new HashMap<String, ByteBuffer>();
             final FontConfig.Family[] xmlFamilies = fontConfig.getFamilies();
@@ -243,16 +256,12 @@
                 if (familyName == null) {
                     continue;
                 }
-                final FontFamily family = createFontFamily(
-                        xmlFamily.getName(), Arrays.asList(xmlFamily.getFonts()),
-                        xmlFamily.getLanguages(), xmlFamily.getVariant(), bufferCache, fontDir,
-                        availableFonts);
-                if (family == null) {
-                    continue;
-                }
-                final ArrayList<FontFamily> fallback = new ArrayList<>();
-                fallback.add(family);
-                fallbackListMap.put(familyName, fallback);
+                appendNamedFamily(xmlFamily, bufferCache, fallbackListMap, availableFonts);
+            }
+
+            for (int i = 0; i < oemCustomization.mAdditionalNamedFamilies.size(); ++i) {
+                appendNamedFamily(oemCustomization.mAdditionalNamedFamilies.get(i),
+                        bufferCache, fallbackListMap, availableFonts);
             }
 
             // Then, add fallback fonts to the each fallback map.
@@ -261,8 +270,7 @@
                 // The first family (usually the sans-serif family) is always placed immediately
                 // after the primary family in the fallback.
                 if (i == 0 || xmlFamily.getName() == null) {
-                    pushFamilyToFallback(xmlFamily, fallbackListMap, bufferCache, fontDir,
-                            availableFonts);
+                    pushFamilyToFallback(xmlFamily, fallbackListMap, bufferCache, availableFonts);
                 }
             }
 
@@ -275,20 +283,36 @@
                 fallbackMap.put(fallbackName, families);
             }
 
-            return fontConfig.getAliases();
+            final ArrayList<FontConfig.Alias> list = new ArrayList<>();
+            list.addAll(Arrays.asList(fontConfig.getAliases()));
+            list.addAll(oemCustomization.mAdditionalAliases);
+            return list.toArray(new FontConfig.Alias[list.size()]);
         } catch (IOException | XmlPullParserException e) {
             Log.e(TAG, "Failed initialize system fallbacks.", e);
             return ArrayUtils.emptyArray(FontConfig.Alias.class);
         }
     }
 
+    private static FontCustomizationParser.Result readFontCustomization(
+            @NonNull String customizeXml, @NonNull String customFontsDir) {
+        try (FileInputStream f = new FileInputStream(customizeXml)) {
+            return FontCustomizationParser.parse(f, customFontsDir);
+        } catch (IOException e) {
+            return new FontCustomizationParser.Result();
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "Failed to parse font customization XML", e);
+            return new FontCustomizationParser.Result();
+        }
+    }
+
     static {
         final ArrayMap<String, FontFamily[]> systemFallbackMap = new ArrayMap<>();
         final ArrayList<Font> availableFonts = new ArrayList<>();
+        final FontCustomizationParser.Result oemCustomization =
+                readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/");
         sAliases = buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/",
-                systemFallbackMap, availableFonts);
+                oemCustomization, systemFallbackMap, availableFonts);
         sSystemFallbackMap = Collections.unmodifiableMap(systemFallbackMap);
         sAvailableFonts = Collections.unmodifiableList(availableFonts);
     }
-
 }
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index bba36bc..74cab92 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -43,8 +43,10 @@
         "AssetManager2.cpp",
         "AttributeResolution.cpp",
         "ChunkIterator.cpp",
+        "ConfigDescription.cpp",
         "Idmap.cpp",
         "LoadedArsc.cpp",
+        "Locale.cpp",
         "LocaleData.cpp",
         "misc.cpp",
         "ObbFile.cpp",
@@ -135,10 +137,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",
diff --git a/libs/androidfw/ConfigDescription.cpp b/libs/androidfw/ConfigDescription.cpp
new file mode 100644
index 0000000..1f3a89e
--- /dev/null
+++ b/libs/androidfw/ConfigDescription.cpp
@@ -0,0 +1,993 @@
+/*
+ * 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 "androidfw/ConfigDescription.h"
+#include "androidfw/Locale.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+#include "androidfw/Util.h"
+
+#include <string>
+#include <vector>
+
+namespace android {
+
+static const char* kWildcardName = "any";
+
+const ConfigDescription& ConfigDescription::DefaultConfig() {
+  static ConfigDescription config = {};
+  return config;
+}
+
+static bool parseMcc(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->mcc = 0;
+    return true;
+  }
+  const char* c = name;
+  if (tolower(*c) != 'm') return false;
+  c++;
+  if (tolower(*c) != 'c') return false;
+  c++;
+  if (tolower(*c) != 'c') return false;
+  c++;
+
+  const char* val = c;
+
+  while (*c >= '0' && *c <= '9') {
+    c++;
+  }
+  if (*c != 0) return false;
+  if (c - val != 3) return false;
+
+  int d = atoi(val);
+  if (d != 0) {
+    if (out) out->mcc = d;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseMnc(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->mnc = 0;
+    return true;
+  }
+  const char* c = name;
+  if (tolower(*c) != 'm') return false;
+  c++;
+  if (tolower(*c) != 'n') return false;
+  c++;
+  if (tolower(*c) != 'c') return false;
+  c++;
+
+  const char* val = c;
+
+  while (*c >= '0' && *c <= '9') {
+    c++;
+  }
+  if (*c != 0) return false;
+  if (c - val == 0 || c - val > 3) return false;
+
+  if (out) {
+    out->mnc = atoi(val);
+    if (out->mnc == 0) {
+      out->mnc = ACONFIGURATION_MNC_ZERO;
+    }
+  }
+
+  return true;
+}
+
+static bool parseLayoutDirection(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
+          ResTable_config::LAYOUTDIR_ANY;
+    return true;
+  } else if (strcmp(name, "ldltr") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
+          ResTable_config::LAYOUTDIR_LTR;
+    return true;
+  } else if (strcmp(name, "ldrtl") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
+          ResTable_config::LAYOUTDIR_RTL;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
+          ResTable_config::SCREENSIZE_ANY;
+    return true;
+  } else if (strcmp(name, "small") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
+          ResTable_config::SCREENSIZE_SMALL;
+    return true;
+  } else if (strcmp(name, "normal") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
+          ResTable_config::SCREENSIZE_NORMAL;
+    return true;
+  } else if (strcmp(name, "large") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
+          ResTable_config::SCREENSIZE_LARGE;
+    return true;
+  } else if (strcmp(name, "xlarge") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
+          ResTable_config::SCREENSIZE_XLARGE;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
+          ResTable_config::SCREENLONG_ANY;
+    return true;
+  } else if (strcmp(name, "long") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
+          ResTable_config::SCREENLONG_YES;
+    return true;
+  } else if (strcmp(name, "notlong") == 0) {
+    if (out)
+      out->screenLayout =
+          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
+          ResTable_config::SCREENLONG_NO;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseScreenRound(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->screenLayout2 =
+          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
+          ResTable_config::SCREENROUND_ANY;
+    return true;
+  } else if (strcmp(name, "round") == 0) {
+    if (out)
+      out->screenLayout2 =
+          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
+          ResTable_config::SCREENROUND_YES;
+    return true;
+  } else if (strcmp(name, "notround") == 0) {
+    if (out)
+      out->screenLayout2 =
+          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
+          ResTable_config::SCREENROUND_NO;
+    return true;
+  }
+  return false;
+}
+
+static bool parseWideColorGamut(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->colorMode =
+          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
+          ResTable_config::WIDE_COLOR_GAMUT_ANY;
+    return true;
+  } else if (strcmp(name, "widecg") == 0) {
+    if (out)
+      out->colorMode =
+          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
+          ResTable_config::WIDE_COLOR_GAMUT_YES;
+    return true;
+  } else if (strcmp(name, "nowidecg") == 0) {
+    if (out)
+      out->colorMode =
+          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
+          ResTable_config::WIDE_COLOR_GAMUT_NO;
+    return true;
+  }
+  return false;
+}
+
+static bool parseHdr(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->colorMode =
+          (out->colorMode & ~ResTable_config::MASK_HDR) |
+          ResTable_config::HDR_ANY;
+    return true;
+  } else if (strcmp(name, "highdr") == 0) {
+    if (out)
+      out->colorMode =
+          (out->colorMode & ~ResTable_config::MASK_HDR) |
+          ResTable_config::HDR_YES;
+    return true;
+  } else if (strcmp(name, "lowdr") == 0) {
+    if (out)
+      out->colorMode =
+          (out->colorMode & ~ResTable_config::MASK_HDR) |
+          ResTable_config::HDR_NO;
+    return true;
+  }
+  return false;
+}
+
+static bool parseOrientation(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->orientation = out->ORIENTATION_ANY;
+    return true;
+  } else if (strcmp(name, "port") == 0) {
+    if (out) out->orientation = out->ORIENTATION_PORT;
+    return true;
+  } else if (strcmp(name, "land") == 0) {
+    if (out) out->orientation = out->ORIENTATION_LAND;
+    return true;
+  } else if (strcmp(name, "square") == 0) {
+    if (out) out->orientation = out->ORIENTATION_SQUARE;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseUiModeType(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_ANY;
+    return true;
+  } else if (strcmp(name, "desk") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_DESK;
+    return true;
+  } else if (strcmp(name, "car") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_CAR;
+    return true;
+  } else if (strcmp(name, "television") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_TELEVISION;
+    return true;
+  } else if (strcmp(name, "appliance") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_APPLIANCE;
+    return true;
+  } else if (strcmp(name, "watch") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_WATCH;
+    return true;
+  } else if (strcmp(name, "vrheadset") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
+                    ResTable_config::UI_MODE_TYPE_VR_HEADSET;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseUiModeNight(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
+                    ResTable_config::UI_MODE_NIGHT_ANY;
+    return true;
+  } else if (strcmp(name, "night") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
+                    ResTable_config::UI_MODE_NIGHT_YES;
+    return true;
+  } else if (strcmp(name, "notnight") == 0) {
+    if (out)
+      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
+                    ResTable_config::UI_MODE_NIGHT_NO;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseDensity(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->density = ResTable_config::DENSITY_DEFAULT;
+    return true;
+  }
+
+  if (strcmp(name, "anydpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_ANY;
+    return true;
+  }
+
+  if (strcmp(name, "nodpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_NONE;
+    return true;
+  }
+
+  if (strcmp(name, "ldpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_LOW;
+    return true;
+  }
+
+  if (strcmp(name, "mdpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_MEDIUM;
+    return true;
+  }
+
+  if (strcmp(name, "tvdpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_TV;
+    return true;
+  }
+
+  if (strcmp(name, "hdpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_HIGH;
+    return true;
+  }
+
+  if (strcmp(name, "xhdpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_XHIGH;
+    return true;
+  }
+
+  if (strcmp(name, "xxhdpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_XXHIGH;
+    return true;
+  }
+
+  if (strcmp(name, "xxxhdpi") == 0) {
+    if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
+    return true;
+  }
+
+  char* c = (char*)name;
+  while (*c >= '0' && *c <= '9') {
+    c++;
+  }
+
+  // check that we have 'dpi' after the last digit.
+  if (toupper(c[0]) != 'D' || toupper(c[1]) != 'P' || toupper(c[2]) != 'I' ||
+      c[3] != 0) {
+    return false;
+  }
+
+  // temporarily replace the first letter with \0 to
+  // use atoi.
+  char tmp = c[0];
+  c[0] = '\0';
+
+  int d = atoi(name);
+  c[0] = tmp;
+
+  if (d != 0) {
+    if (out) out->density = d;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseTouchscreen(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
+    return true;
+  } else if (strcmp(name, "notouch") == 0) {
+    if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
+    return true;
+  } else if (strcmp(name, "stylus") == 0) {
+    if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
+    return true;
+  } else if (strcmp(name, "finger") == 0) {
+    if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseKeysHidden(const char* name, ResTable_config* out) {
+  uint8_t mask = 0;
+  uint8_t value = 0;
+  if (strcmp(name, kWildcardName) == 0) {
+    mask = ResTable_config::MASK_KEYSHIDDEN;
+    value = ResTable_config::KEYSHIDDEN_ANY;
+  } else if (strcmp(name, "keysexposed") == 0) {
+    mask = ResTable_config::MASK_KEYSHIDDEN;
+    value = ResTable_config::KEYSHIDDEN_NO;
+  } else if (strcmp(name, "keyshidden") == 0) {
+    mask = ResTable_config::MASK_KEYSHIDDEN;
+    value = ResTable_config::KEYSHIDDEN_YES;
+  } else if (strcmp(name, "keyssoft") == 0) {
+    mask = ResTable_config::MASK_KEYSHIDDEN;
+    value = ResTable_config::KEYSHIDDEN_SOFT;
+  }
+
+  if (mask != 0) {
+    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseKeyboard(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->keyboard = out->KEYBOARD_ANY;
+    return true;
+  } else if (strcmp(name, "nokeys") == 0) {
+    if (out) out->keyboard = out->KEYBOARD_NOKEYS;
+    return true;
+  } else if (strcmp(name, "qwerty") == 0) {
+    if (out) out->keyboard = out->KEYBOARD_QWERTY;
+    return true;
+  } else if (strcmp(name, "12key") == 0) {
+    if (out) out->keyboard = out->KEYBOARD_12KEY;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseNavHidden(const char* name, ResTable_config* out) {
+  uint8_t mask = 0;
+  uint8_t value = 0;
+  if (strcmp(name, kWildcardName) == 0) {
+    mask = ResTable_config::MASK_NAVHIDDEN;
+    value = ResTable_config::NAVHIDDEN_ANY;
+  } else if (strcmp(name, "navexposed") == 0) {
+    mask = ResTable_config::MASK_NAVHIDDEN;
+    value = ResTable_config::NAVHIDDEN_NO;
+  } else if (strcmp(name, "navhidden") == 0) {
+    mask = ResTable_config::MASK_NAVHIDDEN;
+    value = ResTable_config::NAVHIDDEN_YES;
+  }
+
+  if (mask != 0) {
+    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseNavigation(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) out->navigation = out->NAVIGATION_ANY;
+    return true;
+  } else if (strcmp(name, "nonav") == 0) {
+    if (out) out->navigation = out->NAVIGATION_NONAV;
+    return true;
+  } else if (strcmp(name, "dpad") == 0) {
+    if (out) out->navigation = out->NAVIGATION_DPAD;
+    return true;
+  } else if (strcmp(name, "trackball") == 0) {
+    if (out) out->navigation = out->NAVIGATION_TRACKBALL;
+    return true;
+  } else if (strcmp(name, "wheel") == 0) {
+    if (out) out->navigation = out->NAVIGATION_WHEEL;
+    return true;
+  }
+
+  return false;
+}
+
+static bool parseScreenSize(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) {
+      out->screenWidth = out->SCREENWIDTH_ANY;
+      out->screenHeight = out->SCREENHEIGHT_ANY;
+    }
+    return true;
+  }
+
+  const char* x = name;
+  while (*x >= '0' && *x <= '9') x++;
+  if (x == name || *x != 'x') return false;
+  std::string xName(name, x - name);
+  x++;
+
+  const char* y = x;
+  while (*y >= '0' && *y <= '9') y++;
+  if (y == name || *y != 0) return false;
+  std::string yName(x, y - x);
+
+  uint16_t w = (uint16_t)atoi(xName.c_str());
+  uint16_t h = (uint16_t)atoi(yName.c_str());
+  if (w < h) {
+    return false;
+  }
+
+  if (out) {
+    out->screenWidth = w;
+    out->screenHeight = h;
+  }
+
+  return true;
+}
+
+static bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) {
+      out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
+    }
+    return true;
+  }
+
+  if (*name != 's') return false;
+  name++;
+  if (*name != 'w') return false;
+  name++;
+  const char* x = name;
+  while (*x >= '0' && *x <= '9') x++;
+  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+  std::string xName(name, x - name);
+
+  if (out) {
+    out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
+  }
+
+  return true;
+}
+
+static bool parseScreenWidthDp(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) {
+      out->screenWidthDp = out->SCREENWIDTH_ANY;
+    }
+    return true;
+  }
+
+  if (*name != 'w') return false;
+  name++;
+  const char* x = name;
+  while (*x >= '0' && *x <= '9') x++;
+  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+  std::string xName(name, x - name);
+
+  if (out) {
+    out->screenWidthDp = (uint16_t)atoi(xName.c_str());
+  }
+
+  return true;
+}
+
+static bool parseScreenHeightDp(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) {
+      out->screenHeightDp = out->SCREENWIDTH_ANY;
+    }
+    return true;
+  }
+
+  if (*name != 'h') return false;
+  name++;
+  const char* x = name;
+  while (*x >= '0' && *x <= '9') x++;
+  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+  std::string xName(name, x - name);
+
+  if (out) {
+    out->screenHeightDp = (uint16_t)atoi(xName.c_str());
+  }
+
+  return true;
+}
+
+static bool parseVersion(const char* name, ResTable_config* out) {
+  if (strcmp(name, kWildcardName) == 0) {
+    if (out) {
+      out->sdkVersion = out->SDKVERSION_ANY;
+      out->minorVersion = out->MINORVERSION_ANY;
+    }
+    return true;
+  }
+
+  if (*name != 'v') {
+    return false;
+  }
+
+  name++;
+  const char* s = name;
+  while (*s >= '0' && *s <= '9') s++;
+  if (s == name || *s != 0) return false;
+  std::string sdkName(name, s - name);
+
+  if (out) {
+    out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
+    out->minorVersion = 0;
+  }
+
+  return true;
+}
+
+bool ConfigDescription::Parse(const StringPiece& str, ConfigDescription* out) {
+  std::vector<std::string> parts = util::SplitAndLowercase(str, '-');
+
+  ConfigDescription config;
+  ssize_t parts_consumed = 0;
+  LocaleValue locale;
+
+  const auto parts_end = parts.end();
+  auto part_iter = parts.begin();
+
+  if (str.size() == 0) {
+    goto success;
+  }
+
+  if (parseMcc(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseMnc(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  // Locale spans a few '-' separators, so we let it
+  // control the index.
+  parts_consumed = locale.InitFromParts(part_iter, parts_end);
+  if (parts_consumed < 0) {
+    return false;
+  } else {
+    locale.WriteTo(&config);
+    part_iter += parts_consumed;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseLayoutDirection(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseScreenWidthDp(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseScreenHeightDp(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseScreenLayoutSize(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseScreenLayoutLong(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseScreenRound(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseWideColorGamut(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseHdr(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseOrientation(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseUiModeType(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseUiModeNight(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseDensity(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseTouchscreen(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseKeysHidden(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseKeyboard(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseNavHidden(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseNavigation(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseScreenSize(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  if (parseVersion(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
+      goto success;
+    }
+  }
+
+  // Unrecognized.
+  return false;
+
+success:
+  if (out != NULL) {
+    ApplyVersionForCompatibility(&config);
+    *out = config;
+  }
+  return true;
+}
+
+void ConfigDescription::ApplyVersionForCompatibility(
+    ConfigDescription* config) {
+  uint16_t min_sdk = 0;
+  if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
+                == ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
+            config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT ||
+            config->colorMode & ResTable_config::MASK_HDR) {
+        min_sdk = SDK_O;
+  } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
+    min_sdk = SDK_MARSHMALLOW;
+  } else if (config->density == ResTable_config::DENSITY_ANY) {
+    min_sdk = SDK_LOLLIPOP;
+  } else if (config->smallestScreenWidthDp !=
+                 ResTable_config::SCREENWIDTH_ANY ||
+             config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
+             config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
+    min_sdk = SDK_HONEYCOMB_MR2;
+  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) !=
+                 ResTable_config::UI_MODE_TYPE_ANY ||
+             (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) !=
+                 ResTable_config::UI_MODE_NIGHT_ANY) {
+    min_sdk = SDK_FROYO;
+  } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) !=
+                 ResTable_config::SCREENSIZE_ANY ||
+             (config->screenLayout & ResTable_config::MASK_SCREENLONG) !=
+                 ResTable_config::SCREENLONG_ANY ||
+             config->density != ResTable_config::DENSITY_DEFAULT) {
+    min_sdk = SDK_DONUT;
+  }
+
+  if (min_sdk > config->sdkVersion) {
+    config->sdkVersion = min_sdk;
+  }
+}
+
+ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
+  ConfigDescription copy = *this;
+  copy.sdkVersion = 0;
+  return copy;
+}
+
+std::string ConfigDescription::GetBcp47LanguageTag(bool canonicalize) const {
+  char locale[RESTABLE_MAX_LOCALE_LEN];
+  getBcp47Locale(locale, canonicalize);
+  return std::string(locale);
+}
+
+std::string ConfigDescription::to_string() const {
+  const String8 str = toString();
+  return std::string(str.string(), str.size());
+}
+
+bool ConfigDescription::Dominates(const ConfigDescription& o) const {
+  if (*this == o) {
+    return true;
+  }
+
+  // Locale de-duping is not-trivial, disable for now (b/62409213).
+  if (diff(o) & CONFIG_LOCALE) {
+    return false;
+  }
+
+  if (*this == DefaultConfig()) {
+    return true;
+  }
+  return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
+         !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this);
+}
+
+bool ConfigDescription::HasHigherPrecedenceThan(
+    const ConfigDescription& o) const {
+  // The order of the following tests defines the importance of one
+  // configuration parameter over another. Those tests first are more
+  // important, trumping any values in those following them.
+  // The ordering should be the same as ResTable_config#isBetterThan.
+  if (mcc || o.mcc) return (!o.mcc);
+  if (mnc || o.mnc) return (!o.mnc);
+  if (language[0] || o.language[0]) return (!o.language[0]);
+  if (country[0] || o.country[0]) return (!o.country[0]);
+  // Script and variant require either a language or country, both of which
+  // have higher precedence.
+  if ((screenLayout | o.screenLayout) & MASK_LAYOUTDIR) {
+    return !(o.screenLayout & MASK_LAYOUTDIR);
+  }
+  if (smallestScreenWidthDp || o.smallestScreenWidthDp)
+    return (!o.smallestScreenWidthDp);
+  if (screenWidthDp || o.screenWidthDp) return (!o.screenWidthDp);
+  if (screenHeightDp || o.screenHeightDp) return (!o.screenHeightDp);
+  if ((screenLayout | o.screenLayout) & MASK_SCREENSIZE) {
+    return !(o.screenLayout & MASK_SCREENSIZE);
+  }
+  if ((screenLayout | o.screenLayout) & MASK_SCREENLONG) {
+    return !(o.screenLayout & MASK_SCREENLONG);
+  }
+  if ((screenLayout2 | o.screenLayout2) & MASK_SCREENROUND) {
+    return !(o.screenLayout2 & MASK_SCREENROUND);
+  }
+  if ((colorMode | o.colorMode) & MASK_HDR) {
+    return !(o.colorMode & MASK_HDR);
+  }
+  if ((colorMode | o.colorMode) & MASK_WIDE_COLOR_GAMUT) {
+    return !(o.colorMode & MASK_WIDE_COLOR_GAMUT);
+  }
+  if (orientation || o.orientation) return (!o.orientation);
+  if ((uiMode | o.uiMode) & MASK_UI_MODE_TYPE) {
+    return !(o.uiMode & MASK_UI_MODE_TYPE);
+  }
+  if ((uiMode | o.uiMode) & MASK_UI_MODE_NIGHT) {
+    return !(o.uiMode & MASK_UI_MODE_NIGHT);
+  }
+  if (density || o.density) return (!o.density);
+  if (touchscreen || o.touchscreen) return (!o.touchscreen);
+  if ((inputFlags | o.inputFlags) & MASK_KEYSHIDDEN) {
+    return !(o.inputFlags & MASK_KEYSHIDDEN);
+  }
+  if ((inputFlags | o.inputFlags) & MASK_NAVHIDDEN) {
+    return !(o.inputFlags & MASK_NAVHIDDEN);
+  }
+  if (keyboard || o.keyboard) return (!o.keyboard);
+  if (navigation || o.navigation) return (!o.navigation);
+  if (screenWidth || o.screenWidth) return (!o.screenWidth);
+  if (screenHeight || o.screenHeight) return (!o.screenHeight);
+  if (sdkVersion || o.sdkVersion) return (!o.sdkVersion);
+  if (minorVersion || o.minorVersion) return (!o.minorVersion);
+  // Both configurations have nothing defined except some possible future
+  // value. Returning the comparison of the two configurations is a
+  // "best effort" at this point to protect against incorrect dominations.
+  return *this != o;
+}
+
+bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const {
+  // This method should be updated as new configuration parameters are
+  // introduced (e.g. screenConfig2).
+  auto pred = [](const uint32_t a, const uint32_t b) -> bool {
+    return a == 0 || b == 0 || a == b;
+  };
+  // The values here can be found in ResTable_config#match. Density and range
+  // values can't lead to conflicts, and are ignored.
+  return !pred(mcc, o.mcc) || !pred(mnc, o.mnc) || !pred(locale, o.locale) ||
+         !pred(screenLayout & MASK_LAYOUTDIR,
+               o.screenLayout & MASK_LAYOUTDIR) ||
+         !pred(screenLayout & MASK_SCREENLONG,
+               o.screenLayout & MASK_SCREENLONG) ||
+         !pred(uiMode & MASK_UI_MODE_TYPE, o.uiMode & MASK_UI_MODE_TYPE) ||
+         !pred(uiMode & MASK_UI_MODE_NIGHT, o.uiMode & MASK_UI_MODE_NIGHT) ||
+         !pred(screenLayout2 & MASK_SCREENROUND,
+               o.screenLayout2 & MASK_SCREENROUND) ||
+         !pred(colorMode & MASK_HDR, o.colorMode & MASK_HDR) ||
+         !pred(colorMode & MASK_WIDE_COLOR_GAMUT,
+               o.colorMode & MASK_WIDE_COLOR_GAMUT) ||
+         !pred(orientation, o.orientation) ||
+         !pred(touchscreen, o.touchscreen) ||
+         !pred(inputFlags & MASK_KEYSHIDDEN, o.inputFlags & MASK_KEYSHIDDEN) ||
+         !pred(inputFlags & MASK_NAVHIDDEN, o.inputFlags & MASK_NAVHIDDEN) ||
+         !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation);
+}
+
+bool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const {
+  return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
+}
+
+}  // namespace android
diff --git a/libs/androidfw/Locale.cpp b/libs/androidfw/Locale.cpp
new file mode 100644
index 0000000..2870066
--- /dev/null
+++ b/libs/androidfw/Locale.cpp
@@ -0,0 +1,260 @@
+/*
+ * 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 "androidfw/Locale.h"
+#include "androidfw/Util.h"
+
+#include <ctype.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+using ::android::ResTable_config;
+using ::android::StringPiece;
+
+namespace android {
+
+void LocaleValue::set_language(const char* language_chars) {
+  size_t i = 0;
+  while ((*language_chars) != '\0') {
+    language[i++] = ::tolower(*language_chars);
+    language_chars++;
+  }
+}
+
+void LocaleValue::set_region(const char* region_chars) {
+  size_t i = 0;
+  while ((*region_chars) != '\0') {
+    region[i++] = ::toupper(*region_chars);
+    region_chars++;
+  }
+}
+
+void LocaleValue::set_script(const char* script_chars) {
+  size_t i = 0;
+  while ((*script_chars) != '\0') {
+    if (i == 0) {
+      script[i++] = ::toupper(*script_chars);
+    } else {
+      script[i++] = ::tolower(*script_chars);
+    }
+    script_chars++;
+  }
+}
+
+void LocaleValue::set_variant(const char* variant_chars) {
+  size_t i = 0;
+  while ((*variant_chars) != '\0') {
+    variant[i++] = *variant_chars;
+    variant_chars++;
+  }
+}
+
+static inline bool is_alpha(const std::string& str) {
+  return std::all_of(std::begin(str), std::end(str), ::isalpha);
+}
+
+static inline bool is_number(const std::string& str) {
+  return std::all_of(std::begin(str), std::end(str), ::isdigit);
+}
+
+bool LocaleValue::InitFromFilterString(const StringPiece& str) {
+  // A locale (as specified in the filter) is an underscore separated name such
+  // as "en_US", "en_Latn_US", or "en_US_POSIX".
+  std::vector<std::string> parts = util::SplitAndLowercase(str, '_');
+
+  const int num_tags = parts.size();
+  bool valid = false;
+  if (num_tags >= 1) {
+    const std::string& lang = parts[0];
+    if (is_alpha(lang) && (lang.length() == 2 || lang.length() == 3)) {
+      set_language(lang.c_str());
+      valid = true;
+    }
+  }
+
+  if (!valid || num_tags == 1) {
+    return valid;
+  }
+
+  // At this point, valid == true && numTags > 1.
+  const std::string& part2 = parts[1];
+  if ((part2.length() == 2 && is_alpha(part2)) ||
+      (part2.length() == 3 && is_number(part2))) {
+    set_region(part2.c_str());
+  } else if (part2.length() == 4 && is_alpha(part2)) {
+    set_script(part2.c_str());
+  } else if (part2.length() >= 4 && part2.length() <= 8) {
+    set_variant(part2.c_str());
+  } else {
+    valid = false;
+  }
+
+  if (!valid || num_tags == 2) {
+    return valid;
+  }
+
+  // At this point, valid == true && numTags > 1.
+  const std::string& part3 = parts[2];
+  if (((part3.length() == 2 && is_alpha(part3)) ||
+       (part3.length() == 3 && is_number(part3))) &&
+      script[0]) {
+    set_region(part3.c_str());
+  } else if (part3.length() >= 4 && part3.length() <= 8) {
+    set_variant(part3.c_str());
+  } else {
+    valid = false;
+  }
+
+  if (!valid || num_tags == 3) {
+    return valid;
+  }
+
+  const std::string& part4 = parts[3];
+  if (part4.length() >= 4 && part4.length() <= 8) {
+    set_variant(part4.c_str());
+  } else {
+    valid = false;
+  }
+
+  if (!valid || num_tags > 4) {
+    return false;
+  }
+
+  return true;
+}
+
+bool LocaleValue::InitFromBcp47Tag(const StringPiece& bcp47tag) {
+  return InitFromBcp47TagImpl(bcp47tag, '-');
+}
+
+bool LocaleValue::InitFromBcp47TagImpl(const StringPiece& bcp47tag, const char separator) {
+  std::vector<std::string> subtags = util::SplitAndLowercase(bcp47tag, separator);
+  if (subtags.size() == 1) {
+    set_language(subtags[0].c_str());
+  } else if (subtags.size() == 2) {
+    set_language(subtags[0].c_str());
+
+    // The second tag can either be a region, a variant or a script.
+    switch (subtags[1].size()) {
+      case 2:
+      case 3:
+        set_region(subtags[1].c_str());
+        break;
+      case 4:
+        if ('0' <= subtags[1][0] && subtags[1][0] <= '9') {
+          // This is a variant: fall through
+        } else {
+          set_script(subtags[1].c_str());
+          break;
+        }
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+        set_variant(subtags[1].c_str());
+        break;
+      default:
+        return false;
+    }
+  } else if (subtags.size() == 3) {
+    // The language is always the first subtag.
+    set_language(subtags[0].c_str());
+
+    // The second subtag can either be a script or a region code.
+    // If its size is 4, it's a script code, else it's a region code.
+    if (subtags[1].size() == 4) {
+      set_script(subtags[1].c_str());
+    } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
+      set_region(subtags[1].c_str());
+    } else {
+      return false;
+    }
+
+    // The third tag can either be a region code (if the second tag was
+    // a script), else a variant code.
+    if (subtags[2].size() >= 4) {
+      set_variant(subtags[2].c_str());
+    } else {
+      set_region(subtags[2].c_str());
+    }
+  } else if (subtags.size() == 4) {
+    set_language(subtags[0].c_str());
+    set_script(subtags[1].c_str());
+    set_region(subtags[2].c_str());
+    set_variant(subtags[3].c_str());
+  } else {
+    return false;
+  }
+  return true;
+}
+
+ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
+                                   std::vector<std::string>::iterator end) {
+  const std::vector<std::string>::iterator start_iter = iter;
+
+  std::string& part = *iter;
+  if (part[0] == 'b' && part[1] == '+') {
+    // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags,
+    // except that the separator is "+" and not "-". Skip the prefix 'b+'.
+    if (!InitFromBcp47TagImpl(StringPiece(part).substr(2), '+')) {
+      return -1;
+    }
+    ++iter;
+  } else {
+    if ((part.length() == 2 || part.length() == 3) && is_alpha(part) && part != "car") {
+      set_language(part.c_str());
+      ++iter;
+
+      if (iter != end) {
+        const std::string& region_part = *iter;
+        if (region_part.c_str()[0] == 'r' && region_part.length() == 3) {
+          set_region(region_part.c_str() + 1);
+          ++iter;
+        }
+      }
+    }
+  }
+  return static_cast<ssize_t>(iter - start_iter);
+}
+
+void LocaleValue::InitFromResTable(const ResTable_config& config) {
+  config.unpackLanguage(language);
+  config.unpackRegion(region);
+  if (config.localeScript[0] && !config.localeScriptWasComputed) {
+    memcpy(script, config.localeScript, sizeof(config.localeScript));
+  }
+
+  if (config.localeVariant[0]) {
+    memcpy(variant, config.localeVariant, sizeof(config.localeVariant));
+  }
+}
+
+void LocaleValue::WriteTo(ResTable_config* out) const {
+  out->packLanguage(language);
+  out->packRegion(region);
+
+  if (script[0]) {
+    memcpy(out->localeScript, script, sizeof(out->localeScript));
+  }
+
+  if (variant[0]) {
+    memcpy(out->localeVariant, variant, sizeof(out->localeVariant));
+  }
+}
+
+}  // namespace android
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/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h
new file mode 100644
index 0000000..29424c4
--- /dev/null
+++ b/libs/androidfw/include/androidfw/ConfigDescription.h
@@ -0,0 +1,216 @@
+/*
+ * 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 ANDROIDFW_CONFIG_DESCRIPTION_H
+#define ANDROIDFW_CONFIG_DESCRIPTION_H
+
+#include <ostream>
+
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+
+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 ResTable_config {
+  /**
+   * Returns an immutable default config.
+   */
+  static const ConfigDescription& DefaultConfig();
+
+  /*
+   * Parse a string of the form 'fr-sw600dp-land' and fill in the
+   * given ResTable_config with resulting configuration parameters.
+   *
+   * The resulting configuration has the appropriate sdkVersion defined
+   * for backwards compatibility.
+   */
+  static bool Parse(const android::StringPiece& str, ConfigDescription* out = nullptr);
+
+  /**
+   * If the configuration uses an axis that was added after
+   * the original Android release, make sure the SDK version
+   * is set accordingly.
+   */
+  static void ApplyVersionForCompatibility(ConfigDescription* config);
+
+  ConfigDescription();
+  ConfigDescription(const android::ResTable_config& o);  // NOLINT(implicit)
+  ConfigDescription(const ConfigDescription& o);
+  ConfigDescription(ConfigDescription&& o) noexcept;
+
+  ConfigDescription& operator=(const android::ResTable_config& o);
+  ConfigDescription& operator=(const ConfigDescription& o);
+  ConfigDescription& operator=(ConfigDescription&& o) noexcept;
+
+  ConfigDescription CopyWithoutSdkVersion() const;
+
+  // Returns the BCP-47 language tag of this configuration's locale.
+  std::string GetBcp47LanguageTag(bool canonicalize = false) const;
+
+  std::string to_string() const;
+
+  /**
+   * A configuration X dominates another configuration Y, if X has at least the
+   * precedence of Y and X is strictly more general than Y: for any type defined
+   * by X, the same type is defined by Y with a value equal to or, in the case
+   * of ranges, more specific than that of X.
+   *
+   * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It
+   * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'.
+   */
+  bool Dominates(const ConfigDescription& o) const;
+
+  /**
+   * Returns true if this configuration defines a more important configuration
+   * parameter than o. For example, "en" has higher precedence than "v23",
+   * whereas "en" has the same precedence as "en-v23".
+   */
+  bool HasHigherPrecedenceThan(const ConfigDescription& o) const;
+
+  /**
+   * A configuration conflicts with another configuration if both
+   * configurations define an incompatible configuration parameter. An
+   * incompatible configuration parameter is a non-range, non-density parameter
+   * that is defined in both configurations as a different, non-default value.
+   */
+  bool ConflictsWith(const ConfigDescription& o) const;
+
+  /**
+   * A configuration is compatible with another configuration if both
+   * configurations can match a common concrete device configuration and are
+   * unrelated by domination. For example, land-v11 conflicts with port-v21
+   * but is compatible with v21 (both land-v11 and v21 would match en-land-v23).
+   */
+  bool IsCompatibleWith(const ConfigDescription& o) const;
+
+  bool MatchWithDensity(const ConfigDescription& o) const;
+
+  bool operator<(const ConfigDescription& o) const;
+  bool operator<=(const ConfigDescription& o) const;
+  bool operator==(const ConfigDescription& o) const;
+  bool operator!=(const ConfigDescription& o) const;
+  bool operator>=(const ConfigDescription& o) const;
+  bool operator>(const ConfigDescription& o) const;
+};
+
+inline ConfigDescription::ConfigDescription() {
+  memset(this, 0, sizeof(*this));
+  size = sizeof(android::ResTable_config);
+}
+
+inline ConfigDescription::ConfigDescription(const android::ResTable_config& o) {
+  *static_cast<android::ResTable_config*>(this) = o;
+  size = sizeof(android::ResTable_config);
+}
+
+inline ConfigDescription::ConfigDescription(const ConfigDescription& o) {
+  *static_cast<android::ResTable_config*>(this) = o;
+}
+
+inline ConfigDescription::ConfigDescription(ConfigDescription&& o) noexcept {
+  *this = o;
+}
+
+inline ConfigDescription& ConfigDescription::operator=(
+    const android::ResTable_config& o) {
+  *static_cast<android::ResTable_config*>(this) = o;
+  size = sizeof(android::ResTable_config);
+  return *this;
+}
+
+inline ConfigDescription& ConfigDescription::operator=(
+    const ConfigDescription& o) {
+  *static_cast<android::ResTable_config*>(this) = o;
+  return *this;
+}
+
+inline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) noexcept {
+  *this = o;
+  return *this;
+}
+
+inline bool ConfigDescription::MatchWithDensity(
+    const ConfigDescription& o) const {
+  return match(o) && (density == 0 || density == o.density);
+}
+
+inline bool ConfigDescription::operator<(const ConfigDescription& o) const {
+  return compare(o) < 0;
+}
+
+inline bool ConfigDescription::operator<=(const ConfigDescription& o) const {
+  return compare(o) <= 0;
+}
+
+inline bool ConfigDescription::operator==(const ConfigDescription& o) const {
+  return compare(o) == 0;
+}
+
+inline bool ConfigDescription::operator!=(const ConfigDescription& o) const {
+  return compare(o) != 0;
+}
+
+inline bool ConfigDescription::operator>=(const ConfigDescription& o) const {
+  return compare(o) >= 0;
+}
+
+inline bool ConfigDescription::operator>(const ConfigDescription& o) const {
+  return compare(o) > 0;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+                                  const ConfigDescription& o) {
+  return out << o.toString().string();
+}
+
+}  // namespace android
+
+#endif  // ANDROIDFW_CONFIG_DESCRIPTION_H
diff --git a/libs/androidfw/include/androidfw/Locale.h b/libs/androidfw/include/androidfw/Locale.h
new file mode 100644
index 0000000..484ed79
--- /dev/null
+++ b/libs/androidfw/include/androidfw/Locale.h
@@ -0,0 +1,117 @@
+/*
+ * 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 ANDROIDFW_LOCALE_VALUE_H
+#define ANDROIDFW_LOCALE_VALUE_H
+
+#include <string>
+#include <vector>
+
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+
+namespace android {
+
+/**
+ * A convenience class to build and parse locales.
+ */
+struct LocaleValue {
+  char language[4];
+  char region[4];
+  char script[4];
+  char variant[8];
+
+  inline LocaleValue();
+
+  /**
+   * Initialize this LocaleValue from a config string.
+   */
+  bool InitFromFilterString(const android::StringPiece& config);
+
+  // Initializes this LocaleValue from a BCP-47 locale tag.
+  bool InitFromBcp47Tag(const android::StringPiece& bcp47tag);
+
+  /**
+   * Initialize this LocaleValue from parts of a vector.
+   */
+  ssize_t InitFromParts(std::vector<std::string>::iterator iter,
+                        std::vector<std::string>::iterator end);
+
+  /**
+   * Initialize this LocaleValue from a ResTable_config.
+   */
+  void InitFromResTable(const android::ResTable_config& config);
+
+  /**
+   * Set the locale in a ResTable_config from this LocaleValue.
+   */
+  void WriteTo(android::ResTable_config* out) const;
+
+  inline int compare(const LocaleValue& other) const;
+
+  inline bool operator<(const LocaleValue& o) const;
+  inline bool operator<=(const LocaleValue& o) const;
+  inline bool operator==(const LocaleValue& o) const;
+  inline bool operator!=(const LocaleValue& o) const;
+  inline bool operator>=(const LocaleValue& o) const;
+  inline bool operator>(const LocaleValue& o) const;
+
+ private:
+  bool InitFromBcp47TagImpl(const android::StringPiece& bcp47tag, const char separator);
+
+  void set_language(const char* language);
+  void set_region(const char* language);
+  void set_script(const char* script);
+  void set_variant(const char* variant);
+};
+
+//
+// Implementation
+//
+
+LocaleValue::LocaleValue() { memset(this, 0, sizeof(LocaleValue)); }
+
+int LocaleValue::compare(const LocaleValue& other) const {
+  return memcmp(this, &other, sizeof(LocaleValue));
+}
+
+bool LocaleValue::operator<(const LocaleValue& o) const {
+  return compare(o) < 0;
+}
+
+bool LocaleValue::operator<=(const LocaleValue& o) const {
+  return compare(o) <= 0;
+}
+
+bool LocaleValue::operator==(const LocaleValue& o) const {
+  return compare(o) == 0;
+}
+
+bool LocaleValue::operator!=(const LocaleValue& o) const {
+  return compare(o) != 0;
+}
+
+bool LocaleValue::operator>=(const LocaleValue& o) const {
+  return compare(o) >= 0;
+}
+
+bool LocaleValue::operator>(const LocaleValue& o) const {
+  return compare(o) > 0;
+}
+
+}  // namespace android
+
+#endif  // ANDROIDFW_LOCALE_VALUE_H
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index e4cd6a8..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"
 
@@ -47,11 +48,11 @@
   constexpr unique_cptr() : ptr_(nullptr) {}
   constexpr unique_cptr(std::nullptr_t) : ptr_(nullptr) {}
   explicit unique_cptr(pointer ptr) : ptr_(ptr) {}
-  unique_cptr(unique_cptr&& o) : ptr_(o.ptr_) { o.ptr_ = nullptr; }
+  unique_cptr(unique_cptr&& o) noexcept : ptr_(o.ptr_) { o.ptr_ = nullptr; }
 
   ~unique_cptr() { std::free(reinterpret_cast<void*>(ptr_)); }
 
-  inline unique_cptr& operator=(unique_cptr&& o) {
+  inline unique_cptr& operator=(unique_cptr&& o) noexcept {
     if (&o == this) {
       return *this;
     }
@@ -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/tests/ConfigDescription_test.cpp b/libs/androidfw/tests/ConfigDescription_test.cpp
new file mode 100644
index 0000000..ce7f805
--- /dev/null
+++ b/libs/androidfw/tests/ConfigDescription_test.cpp
@@ -0,0 +1,157 @@
+/*
+ * 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 "androidfw/ConfigDescription.h"
+#include "androidfw/StringPiece.h"
+
+#include "android-base/logging.h"
+
+#include "gtest/gtest.h"
+
+#include <string>
+
+namespace android {
+
+static ::testing::AssertionResult TestParse(
+    const StringPiece& input, ConfigDescription* config = nullptr) {
+  if (ConfigDescription::Parse(input, config)) {
+    return ::testing::AssertionSuccess() << input << " was successfully parsed";
+  }
+  return ::testing::AssertionFailure() << input << " could not be parsed";
+}
+
+TEST(ConfigDescriptionTest, ParseFailWhenQualifiersAreOutOfOrder) {
+  EXPECT_FALSE(TestParse("en-sw600dp-ldrtl"));
+  EXPECT_FALSE(TestParse("land-en"));
+  EXPECT_FALSE(TestParse("hdpi-320dpi"));
+}
+
+TEST(ConfigDescriptionTest, ParseFailWhenQualifiersAreNotMatched) {
+  EXPECT_FALSE(TestParse("en-sw600dp-ILLEGAL"));
+}
+
+TEST(ConfigDescriptionTest, ParseFailWhenQualifiersHaveTrailingDash) {
+  EXPECT_FALSE(TestParse("en-sw600dp-land-"));
+}
+
+TEST(ConfigDescriptionTest, ParseBasicQualifiers) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("", &config));
+  EXPECT_EQ(std::string(""), config.toString().string());
+
+  EXPECT_TRUE(TestParse("fr-land", &config));
+  EXPECT_EQ(std::string("fr-land"), config.toString().string());
+
+  EXPECT_TRUE(
+      TestParse("mcc310-pl-sw720dp-normal-long-port-night-"
+                "xhdpi-keyssoft-qwerty-navexposed-nonav",
+                &config));
+  EXPECT_EQ(std::string("mcc310-pl-sw720dp-normal-long-port-night-"
+                        "xhdpi-keyssoft-qwerty-navexposed-nonav-v13"),
+            config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseLocales) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("en-rUS", &config));
+  EXPECT_EQ(std::string("en-rUS"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseQualifierAddedInApi13) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("sw600dp", &config));
+  EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
+
+  EXPECT_TRUE(TestParse("sw600dp-v8", &config));
+  EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseCarAttribute) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("car", &config));
+  EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_CAR, config.uiMode);
+}
+
+TEST(ConfigDescriptionTest, TestParsingRoundQualifier) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("round", &config));
+  EXPECT_EQ(android::ResTable_config::SCREENROUND_YES,
+            config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);
+  EXPECT_EQ(SDK_MARSHMALLOW, config.sdkVersion);
+  EXPECT_EQ(std::string("round-v23"), config.toString().string());
+
+  EXPECT_TRUE(TestParse("notround", &config));
+  EXPECT_EQ(android::ResTable_config::SCREENROUND_NO,
+            config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);
+  EXPECT_EQ(SDK_MARSHMALLOW, config.sdkVersion);
+  EXPECT_EQ(std::string("notround-v23"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, TestWideColorGamutQualifier) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("widecg", &config));
+  EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_YES,
+            config.colorMode & android::ResTable_config::MASK_WIDE_COLOR_GAMUT);
+  EXPECT_EQ(SDK_O, config.sdkVersion);
+  EXPECT_EQ(std::string("widecg-v26"), config.toString().string());
+
+  EXPECT_TRUE(TestParse("nowidecg", &config));
+  EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_NO,
+            config.colorMode & android::ResTable_config::MASK_WIDE_COLOR_GAMUT);
+  EXPECT_EQ(SDK_O, config.sdkVersion);
+  EXPECT_EQ(std::string("nowidecg-v26"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, TestHdrQualifier) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("highdr", &config));
+  EXPECT_EQ(android::ResTable_config::HDR_YES,
+            config.colorMode & android::ResTable_config::MASK_HDR);
+  EXPECT_EQ(SDK_O, config.sdkVersion);
+  EXPECT_EQ(std::string("highdr-v26"), config.toString().string());
+
+  EXPECT_TRUE(TestParse("lowdr", &config));
+  EXPECT_EQ(android::ResTable_config::HDR_NO,
+            config.colorMode & android::ResTable_config::MASK_HDR);
+  EXPECT_EQ(SDK_O, config.sdkVersion);
+  EXPECT_EQ(std::string("lowdr-v26"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseVrAttribute) {
+  ConfigDescription config;
+  EXPECT_TRUE(TestParse("vrheadset", &config));
+  EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_VR_HEADSET, config.uiMode);
+  EXPECT_EQ(SDK_O, config.sdkVersion);
+  EXPECT_EQ(std::string("vrheadset-v26"), config.toString().string());
+}
+
+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")));
+  EXPECT_FALSE(ParseConfigOrDie("v11").ConflictsWith(ParseConfigOrDie("v21")));
+  EXPECT_FALSE(ParseConfigOrDie("h600dp").ConflictsWith(ParseConfigOrDie("h300dp")));
+  EXPECT_FALSE(ParseConfigOrDie("w400dp").ConflictsWith(ParseConfigOrDie("w300dp")));
+  EXPECT_FALSE(ParseConfigOrDie("600x400").ConflictsWith(ParseConfigOrDie("300x200")));
+}
+
+}  // namespace android
diff --git a/libs/androidfw/tests/Locale_test.cpp b/libs/androidfw/tests/Locale_test.cpp
new file mode 100644
index 0000000..6b2ef5f
--- /dev/null
+++ b/libs/androidfw/tests/Locale_test.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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 "androidfw/Locale.h"
+#include "androidfw/Util.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+
+namespace android {
+
+static ::testing::AssertionResult TestLanguage(const char* input,
+                                               const char* lang) {
+  std::vector<std::string> parts = util::SplitAndLowercase(input, '-');
+  LocaleValue lv;
+  ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts));
+  if (count < 0) {
+    return ::testing::AssertionFailure() << " failed to parse '" << input
+                                         << "'.";
+  }
+
+  if (count != 1) {
+    return ::testing::AssertionFailure()
+           << count << " parts were consumed parsing '" << input
+           << "' but expected 1.";
+  }
+
+  if (memcmp(lv.language, lang, std::min(strlen(lang), sizeof(lv.language))) !=
+      0) {
+    return ::testing::AssertionFailure()
+           << "expected " << lang << " but got "
+           << std::string(lv.language, sizeof(lv.language)) << ".";
+  }
+
+  return ::testing::AssertionSuccess();
+}
+
+static ::testing::AssertionResult TestLanguageRegion(const char* input,
+                                                     const char* lang,
+                                                     const char* region) {
+  std::vector<std::string> parts = util::SplitAndLowercase(input, '-');
+  LocaleValue lv;
+  ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts));
+  if (count < 0) {
+    return ::testing::AssertionFailure() << " failed to parse '" << input
+                                         << "'.";
+  }
+
+  if (count != 2) {
+    return ::testing::AssertionFailure()
+           << count << " parts were consumed parsing '" << input
+           << "' but expected 2.";
+  }
+
+  if (memcmp(lv.language, lang, std::min(strlen(lang), sizeof(lv.language))) !=
+      0) {
+    return ::testing::AssertionFailure()
+           << "expected " << input << " but got "
+           << std::string(lv.language, sizeof(lv.language)) << ".";
+  }
+
+  if (memcmp(lv.region, region, std::min(strlen(region), sizeof(lv.region))) !=
+      0) {
+    return ::testing::AssertionFailure()
+           << "expected " << region << " but got "
+           << std::string(lv.region, sizeof(lv.region)) << ".";
+  }
+
+  return ::testing::AssertionSuccess();
+}
+
+TEST(ConfigDescriptionTest, ParseLanguage) {
+  EXPECT_TRUE(TestLanguage("en", "en"));
+  EXPECT_TRUE(TestLanguage("fr", "fr"));
+  EXPECT_FALSE(TestLanguage("land", ""));
+  EXPECT_TRUE(TestLanguage("fr-land", "fr"));
+
+  EXPECT_TRUE(TestLanguageRegion("fr-rCA", "fr", "CA"));
+}
+
+}  // namespace android
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 11dad2e..494e513 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -229,6 +229,7 @@
         "ResourceCache.cpp",
         "SkiaCanvas.cpp",
         "Snapshot.cpp",
+        "TreeInfo.cpp",
         "VectorDrawable.cpp",
         "protos/graphicsstats.proto",
     ],
diff --git a/libs/hwui/CanvasTransform.cpp b/libs/hwui/CanvasTransform.cpp
index adcdc18..06e937a 100644
--- a/libs/hwui/CanvasTransform.cpp
+++ b/libs/hwui/CanvasTransform.cpp
@@ -28,6 +28,7 @@
 #include <cmath>
 
 #include <log/log.h>
+#include <SkHighContrastFilter.h>
 
 namespace android::uirenderer {
 
@@ -78,7 +79,6 @@
         info.fColors = _colorStorage.data();
         info.fColorOffsets = _offsetStorage.data();
         SkShader::GradientType type = paint.getShader()->asAGradient(&info);
-        ALOGW_IF(type, "Found gradient of type = %d", type);
 
         if (info.fColorCount <= 10) {
             switch (type) {
@@ -107,10 +107,43 @@
     }
 }
 
+static BitmapPalette paletteForColorHSV(SkColor color) {
+    float hsv[3];
+    SkColorToHSV(color, hsv);
+    return hsv[2] >= .5f ? BitmapPalette::Light : BitmapPalette::Dark;
+}
+
+static BitmapPalette filterPalette(const SkPaint* paint, BitmapPalette palette) {
+    if (palette == BitmapPalette::Unknown || !paint || !paint->getColorFilter()) {
+        return palette;
+    }
+
+    SkColor color = palette == BitmapPalette::Light ? SK_ColorWHITE : SK_ColorBLACK;
+    color = paint->getColorFilter()->filterColor(color);
+    return paletteForColorHSV(color);
+}
+
 bool transformPaint(ColorTransform transform, SkPaint* paint) {
     // TODO
     applyColorTransform(transform, *paint);
     return true;
 }
 
+bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette palette) {
+    palette = filterPalette(paint, palette);
+    bool shouldInvert = false;
+    if (palette == BitmapPalette::Light && transform == ColorTransform::Dark) {
+        shouldInvert = true;
+    }
+    if (palette == BitmapPalette::Dark && transform == ColorTransform::Light) {
+        shouldInvert = true;
+    }
+    if (shouldInvert) {
+        SkHighContrastConfig config;
+        config.fInvertStyle = SkHighContrastConfig::InvertStyle::kInvertLightness;
+        paint->setColorFilter(SkHighContrastFilter::Make(config)->makeComposed(paint->refColorFilter()));
+    }
+    return shouldInvert;
+}
+
 };  // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/CanvasTransform.h b/libs/hwui/CanvasTransform.h
index 32d9a05..e723d64 100644
--- a/libs/hwui/CanvasTransform.h
+++ b/libs/hwui/CanvasTransform.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include "hwui/Bitmap.h"
+
 #include <SkCanvas.h>
 #include <SkPaintFilterCanvas.h>
 
@@ -26,6 +28,7 @@
 enum class UsageHint {
     Unknown = 0,
     Background = 1,
+    Foreground = 2,
 };
 
 enum class ColorTransform {
@@ -37,4 +40,6 @@
 // True if the paint was modified, false otherwise
 bool transformPaint(ColorTransform transform, SkPaint* paint);
 
+bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette palette);
+
 }  // namespace android::uirenderer;
\ No newline at end of file
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 837d546..b772e5b 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -29,12 +29,16 @@
         , mGLContextAttached(false)
         , mUpdateTexImage(false)
         , mLayer(nullptr) {
-    renderState.registerDeferredLayerUpdater(this);
+    renderState.registerContextCallback(this);
 }
 
 DeferredLayerUpdater::~DeferredLayerUpdater() {
     setTransform(nullptr);
-    mRenderState.unregisterDeferredLayerUpdater(this);
+    mRenderState.removeContextCallback(this);
+    destroyLayer();
+}
+
+void DeferredLayerUpdater::onContextDestroyed() {
     destroyLayer();
 }
 
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 4c323b8..b2c5131 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -27,6 +27,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
+#include "renderstate/RenderState.h"
 #include "surfacetexture/SurfaceTexture.h"
 #include "Layer.h"
 #include "Rect.h"
@@ -38,7 +39,7 @@
 
 // Container to hold the properties a layer should be set to at the start
 // of a render pass
-class DeferredLayerUpdater : public VirtualLightRefBase {
+class DeferredLayerUpdater : public VirtualLightRefBase, public IGpuContextCallback {
 public:
     // Note that DeferredLayerUpdater assumes it is taking ownership of the layer
     // and will not call incrementRef on it as a result.
@@ -98,6 +99,9 @@
 
     void destroyLayer();
 
+protected:
+    void onContextDestroyed() override;
+
 private:
     RenderState& mRenderState;
 
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 21fbbdc..0b9d82b 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -61,18 +61,6 @@
     return displayInfo;
 }
 
-void QueryCompositionPreference(ui::Dataspace* dataSpace,
-                                ui::PixelFormat* pixelFormat) {
-    if (Properties::isolatedProcess) {
-        *dataSpace = ui::Dataspace::V0_SRGB;
-        *pixelFormat = ui::PixelFormat::RGBA_8888;
-    }
-
-    status_t status =
-            SurfaceComposerClient::getCompositionPreference(dataSpace, pixelFormat);
-    LOG_ALWAYS_FATAL_IF(status, "Failed to get composition preference, error %d", status);
-}
-
 DeviceInfo::DeviceInfo() {
 #if HWUI_NULL_GPU
         mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
@@ -80,7 +68,6 @@
         mMaxTextureSize = -1;
 #endif
     mDisplayInfo = QueryDisplayInfo();
-    QueryCompositionPreference(&mTargetDataSpace, &mTargetPixelFormat);
 }
 
 int DeviceInfo::maxTextureSize() const {
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 1d747741..5956215 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -17,7 +17,6 @@
 #define DEVICEINFO_H
 
 #include <ui/DisplayInfo.h>
-#include <ui/GraphicTypes.h>
 
 #include "utils/Macros.h"
 
@@ -37,9 +36,6 @@
     // this value is only valid after the GPU has been initialized and there is a valid graphics
     // context or if you are using the HWUI_NULL_GPU
     int maxTextureSize() const;
-
-    ui::Dataspace getTargetDataSpace() const { return mTargetDataSpace; }
-    ui::PixelFormat getTargetPixelFormat() const { return mTargetPixelFormat; }
     const DisplayInfo& displayInfo() const { return mDisplayInfo; }
 
 private:
@@ -50,10 +46,6 @@
 
     int mMaxTextureSize;
     DisplayInfo mDisplayInfo;
-
-    // TODO(lpy) Replace below with android_ prefix types.
-    ui::Dataspace mTargetDataSpace;
-    ui::PixelFormat mTargetPixelFormat;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in
index f61c156..04cf611 100644
--- a/libs/hwui/DisplayListOps.in
+++ b/libs/hwui/DisplayListOps.in
@@ -49,4 +49,5 @@
 X(DrawPoints) 
 X(DrawVertices) 
 X(DrawAtlas) 
-X(DrawShadowRec)
\ No newline at end of file
+X(DrawShadowRec)
+X(DrawVectorDrawable)
\ No newline at end of file
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index e6d2a6f..f2d50cd 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -146,7 +146,7 @@
                              frame[FrameInfoIndex::IntendedVsync] + mFrameInterval);
 
     // If we hit the deadline, cool!
-    if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadline) {
+    if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadline || totalDuration < mFrameInterval) {
         if (isTripleBuffered) {
             mData->reportJankType(JankType::kHighInputLatency);
             (*mGlobalData)->reportJankType(JankType::kHighInputLatency);
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index cc95051..32aaa54 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -77,5 +77,13 @@
     mRenderState.postDecStrong(this);
 }
 
+SkBlendMode Layer::getMode() const {
+    if (mBlend || mode != SkBlendMode::kSrcOver) {
+        return mode;
+    } else {
+        return SkBlendMode::kSrc;
+    }
+}
+
 };  // namespace uirenderer
 };  // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 6f07a43..e4f96e9 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -67,7 +67,7 @@
 
     inline int getAlpha() const { return alpha; }
 
-    inline SkBlendMode getMode() const { return mode; }
+    SkBlendMode getMode() const;
 
     inline SkColorFilter* getColorFilter() const { return mColorFilter.get(); }
 
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 17bec19..a699e2f 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -61,6 +61,7 @@
 bool Properties::disableVsync = false;
 bool Properties::skpCaptureEnabled = false;
 bool Properties::forceDarkMode = false;
+bool Properties::enableForceDarkSupport = false;
 bool Properties::enableRTAnimations = true;
 
 bool Properties::runningInEmulator = false;
@@ -149,6 +150,9 @@
 
     forceDarkMode = property_get_bool(PROPERTY_FORCE_DARK, false);
 
+    // TODO: make this on by default
+    enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, false);
+
     return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw) ||
            (prevDebugStencilClip != debugStencilClip);
 }
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index ea017a7..542bc71 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -192,6 +192,8 @@
 
 #define PROPERTY_FORCE_DARK "debug.hwui.force_dark"
 
+#define PROPERTY_ENABLE_FORCE_DARK "debug.hwui.force_dark_enabled"
+
 ///////////////////////////////////////////////////////////////////////////////
 // Misc
 ///////////////////////////////////////////////////////////////////////////////
@@ -266,6 +268,7 @@
 
     static bool skpCaptureEnabled;
     static bool forceDarkMode;
+    static bool enableForceDarkSupport;
 
     // For experimentation b/68769804
     ANDROID_API static bool enableRTAnimations;
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 3eaff03..f928de9 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -16,11 +16,14 @@
 
 #include "RecordingCanvas.h"
 
+#include "VectorDrawable.h"
+
 #include "SkCanvas.h"
 #include "SkData.h"
 #include "SkDrawShadowInfo.h"
 #include "SkImage.h"
 #include "SkImageFilter.h"
+#include "SkLatticeIter.h"
 #include "SkMath.h"
 #include "SkPicture.h"
 #include "SkRSXform.h"
@@ -278,8 +281,9 @@
 
 struct DrawImage final : Op {
     static const auto kType = Type::DrawImage;
-    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint)
-            : image(std::move(image)), x(x), y(y) {
+    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;
         }
@@ -287,6 +291,7 @@
     sk_sp<const SkImage> image;
     SkScalar x, y;
     SkPaint paint;
+    BitmapPalette palette;
     void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); }
 };
 struct DrawImageNine final : Op {
@@ -309,8 +314,9 @@
 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)
-            : image(std::move(image)), dst(dst), constraint(constraint) {
+                  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) {
             this->paint = *paint;
@@ -320,6 +326,7 @@
     SkRect src, dst;
     SkPaint paint;
     SkCanvas::SrcRectConstraint constraint;
+    BitmapPalette palette;
     void draw(SkCanvas* c, const SkMatrix&) const {
         c->drawImageRect(image.get(), src, dst, &paint, constraint);
     }
@@ -327,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;
         }
@@ -338,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));
@@ -496,6 +510,24 @@
     SkDrawShadowRec fRec;
     void draw(SkCanvas* c, const SkMatrix&) const { c->private_draw_shadow_rec(fPath, fRec); }
 };
+
+struct DrawVectorDrawable final : Op {
+    static const auto kType = Type::DrawVectorDrawable;
+    DrawVectorDrawable(VectorDrawableRoot* tree)
+            : mRoot(tree)
+            , mBounds(tree->stagingProperties().getBounds())
+            , palette(tree->computePalette()) {
+        // Recording, so use staging properties
+        tree->getPaintFor(&paint, tree->stagingProperties());
+    }
+
+    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>
@@ -609,8 +641,8 @@
     this->push<DrawPicture>(0, picture, matrix, paint);
 }
 void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
-                                const SkPaint* paint) {
-    this->push<DrawImage>(0, std::move(image), x, y, paint);
+                                const SkPaint* paint, BitmapPalette palette) {
+    this->push<DrawImage>(0, std::move(image), x, y, paint, palette);
 }
 void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& center,
                                     const SkRect& dst, const SkPaint* paint) {
@@ -618,18 +650,19 @@
 }
 void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
                                     const SkRect& dst, const SkPaint* paint,
-                                    SkCanvas::SrcRectConstraint constraint) {
-    this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint);
+                                    SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) {
+    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);
 }
@@ -638,28 +671,33 @@
                                const SkPaint& paint) {
     void* pod = this->push<DrawText>(bytes, bytes, x, y, paint);
     copy_v(pod, (const char*)text, bytes);
+    mHasText = true;
 }
 void DisplayListData::drawPosText(const void* text, size_t bytes, const SkPoint pos[],
                                   const SkPaint& paint) {
     int n = paint.countText(text, bytes);
     void* pod = this->push<DrawPosText>(n * sizeof(SkPoint) + bytes, bytes, paint, n);
     copy_v(pod, pos, n, (const char*)text, bytes);
+    mHasText = true;
 }
 void DisplayListData::drawPosTextH(const void* text, size_t bytes, const SkScalar xs[], SkScalar y,
                                    const SkPaint& paint) {
     int n = paint.countText(text, bytes);
     void* pod = this->push<DrawPosTextH>(n * sizeof(SkScalar) + bytes, bytes, y, paint, n);
     copy_v(pod, xs, n, (const char*)text, bytes);
+    mHasText = true;
 }
 void DisplayListData::drawTextRSXform(const void* text, size_t bytes, const SkRSXform xforms[],
                                       const SkRect* cull, const SkPaint& paint) {
     int n = paint.countText(text, bytes);
     void* pod = this->push<DrawTextRSXform>(bytes + n * sizeof(SkRSXform), bytes, n, cull, paint);
     copy_v(pod, xforms, n, (const char*)text, bytes);
+    mHasText = true;
 }
 void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                    const SkPaint& paint) {
     this->push<DrawTextBlob>(0, blob, x, y, paint);
+    mHasText = true;
 }
 
 void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4],
@@ -691,6 +729,9 @@
 void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
     this->push<DrawShadowRec>(0, path, rec);
 }
+void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) {
+    this->push<DrawVectorDrawable>(0, tree);
+}
 
 typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
 typedef void (*void_fn)(const void*);
@@ -733,17 +774,36 @@
 }
 
 template <class T>
-using has_paint_t = decltype(std::declval<T>().paint);
+using has_paint_helper = decltype(std::declval<T>().paint);
+
+template <class T>
+constexpr bool has_paint = std::experimental::is_detected_v<has_paint_helper, T>;
+
+template <class T>
+using has_palette_helper = decltype(std::declval<T>().palette);
+
+template <class T>
+constexpr bool has_palette = std::experimental::is_detected_v<has_palette_helper, T>;
 
 template <class T>
 constexpr color_transform_fn colorTransformForOp() {
     if
-        constexpr(std::experimental::is_detected_v<has_paint_t, T>) {
-            return [](const void* op, ColorTransform transform) {
+        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
-                transformPaint(transform,
-                               const_cast<SkPaint*>(&(reinterpret_cast<const T*>(op)->paint)));
+                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 {
@@ -875,7 +935,7 @@
 
 void RecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y,
                                    const SkPaint* paint) {
-    fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint);
+    fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint, BitmapPalette::Unknown);
 }
 void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst,
                                        const SkPaint* paint) {
@@ -883,16 +943,50 @@
 }
 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);
+    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,
+                                const SkPaint* paint, BitmapPalette palette) {
+    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) {
+    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);
+    fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
 }
 void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst,
                                       const SkPaint* paint) {
@@ -900,11 +994,11 @@
 }
 void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst,
                                       const SkPaint* paint, SrcRectConstraint constraint) {
-    fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint);
+    fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown);
 }
 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],
@@ -917,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[],
@@ -930,5 +1024,9 @@
     fDL->drawShadowRec(path, rec);
 }
 
+void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
+    fDL->drawVectorDrawable(tree);
+}
+
 };  // namespace uirenderer
 };  // namespace android
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 32ce1d3..099e0be 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include "CanvasTransform.h"
+#include "hwui/Bitmap.h"
 #include "hwui/Canvas.h"
 #include "utils/Macros.h"
 #include "utils/TypeLogic.h"
@@ -53,6 +54,7 @@
 
 class DisplayListData final {
 public:
+    DisplayListData() : mHasText(false) {}
     ~DisplayListData();
 
     void draw(SkCanvas* canvas) const;
@@ -62,6 +64,8 @@
 
     void applyColorTransform(ColorTransform transform);
 
+    bool hasText() const { return mHasText; }
+
 private:
     friend class RecordingCanvas;
 
@@ -101,12 +105,12 @@
     void drawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*, const SkPaint&);
     void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);
 
-    void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*);
+    void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette);
     void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
     void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
-                       SkCanvas::SrcRectConstraint);
+                       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&);
@@ -116,6 +120,7 @@
     void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
                    SkBlendMode, const SkRect*, const SkPaint*);
     void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
+    void drawVectorDrawable(VectorDrawableRoot* tree);
 
     template <typename T, typename... Args>
     void* push(size_t, Args&&...);
@@ -126,6 +131,8 @@
     SkAutoTMalloc<uint8_t> fBytes;
     size_t fUsed = 0;
     size_t fReserved = 0;
+
+    bool mHasText : 1;
 };
 
 class RecordingCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
@@ -178,6 +185,14 @@
     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 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;
     void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
@@ -193,6 +208,8 @@
                      SkBlendMode, const SkRect*, const SkPaint*) override;
     void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
 
+    void drawVectorDrawable(VectorDrawableRoot* tree);
+
 private:
     typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED;
 
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index d5afb20..d2a8f02 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -112,7 +112,9 @@
     LOG_ALWAYS_FATAL_IF(!info.damageAccumulator, "DamageAccumulator missing");
     MarkAndSweepRemoved observer(&info);
 
+    const int before = info.disableForceDark;
     prepareTreeImpl(observer, info, false);
+    LOG_ALWAYS_FATAL_IF(before != info.disableForceDark, "Mis-matched force dark");
 }
 
 void RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
@@ -158,7 +160,7 @@
         CC_UNLIKELY(properties().getWidth() == 0) || CC_UNLIKELY(properties().getHeight() == 0) ||
         CC_UNLIKELY(!properties().fitsOnLayer())) {
         if (CC_UNLIKELY(hasLayer())) {
-            renderthread::CanvasContext::destroyLayer(this);
+            this->setLayerSurface(nullptr);
         }
         return;
     }
@@ -195,6 +197,11 @@
     if (info.mode == TreeInfo::MODE_FULL) {
         pushStagingPropertiesChanges(info);
     }
+
+    if (!mProperties.getAllowForceDark()) {
+        info.disableForceDark++;
+    }
+
     uint32_t animatorDirtyMask = 0;
     if (CC_LIKELY(info.runAnimations)) {
         animatorDirtyMask = mAnimatorManager.animate(info);
@@ -232,6 +239,9 @@
     }
     pushLayerUpdate(info);
 
+    if (!mProperties.getAllowForceDark()) {
+        info.disableForceDark--;
+    }
     info.damageAccumulator->popTransform();
 }
 
@@ -272,21 +282,45 @@
     mStagingDisplayList = nullptr;
     if (mDisplayList) {
         mDisplayList->syncContents();
-        if (CC_UNLIKELY(Properties::forceDarkMode)) {
-            auto usage = usageHint();
-            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);
+        handleForceDark(info);
+    }
+}
+
+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) {
@@ -313,7 +347,7 @@
 
 void RenderNode::destroyHardwareResources(TreeInfo* info) {
     if (hasLayer()) {
-        renderthread::CanvasContext::destroyLayer(this);
+        this->setLayerSurface(nullptr);
     }
     setStagingDisplayList(nullptr);
 
@@ -323,7 +357,7 @@
 
 void RenderNode::destroyLayers() {
     if (hasLayer()) {
-        renderthread::CanvasContext::destroyLayer(this);
+        this->setLayerSurface(nullptr);
     }
     if (mDisplayList) {
         mDisplayList->updateChildren([](RenderNode* child) { child->destroyLayers(); });
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 83b0c22..be0b46b 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -107,7 +107,7 @@
     bool isRenderable() const { return mDisplayList && !mDisplayList->isEmpty(); }
 
     bool hasProjectionReceiver() const {
-        return mDisplayList && mDisplayList->projectionReceiveIndex >= 0;
+        return mDisplayList && mDisplayList->containsProjectionReceiver();
     }
 
     const char* getName() const { return mName.string(); }
@@ -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/RenderProperties.h b/libs/hwui/RenderProperties.h
index 7966845..04379ae 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -535,6 +535,14 @@
         return CC_UNLIKELY(promotedToLayer()) ? LayerType::RenderLayer : mLayerProperties.mType;
     }
 
+    bool setAllowForceDark(bool allow) {
+        return RP_SET(mPrimitiveFields.mAllowForceDark, allow);
+    }
+
+    bool getAllowForceDark() const {
+        return mPrimitiveFields.mAllowForceDark;
+    }
+
 private:
     // Rendering properties
     struct PrimitiveFields {
@@ -554,6 +562,7 @@
         bool mMatrixOrPivotDirty = false;
         bool mProjectBackwards = false;
         bool mProjectionReceiver = false;
+        bool mAllowForceDark = true;
         Rect mClipBounds;
         Outline mOutline;
         RevealClip mRevealClip;
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/TreeInfo.cpp b/libs/hwui/TreeInfo.cpp
new file mode 100644
index 0000000..808a12a
--- /dev/null
+++ b/libs/hwui/TreeInfo.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TreeInfo.h"
+
+#include "renderthread/CanvasContext.h"
+
+namespace android::uirenderer {
+
+TreeInfo::TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContext)
+        : mode(mode)
+        , prepareTextures(mode == MODE_FULL)
+        , canvasContext(canvasContext)
+        , disableForceDark(canvasContext.useForceDark() ? 0 : 1) {}
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index f2766d6..a0d9605 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include "Properties.h"
 #include "utils/Macros.h"
 
 #include <utils/Timers.h>
@@ -39,7 +40,7 @@
     virtual void onError(const std::string& message) = 0;
 
 protected:
-    virtual ~ErrorHandler() {}
+    virtual ~ErrorHandler() = default;
 };
 
 class TreeObserver {
@@ -51,7 +52,7 @@
     virtual void onMaybeRemovedFromTree(RenderNode* node) = 0;
 
 protected:
-    virtual ~TreeObserver() {}
+    virtual ~TreeObserver() = default;
 };
 
 // This would be a struct, but we want to PREVENT_COPY_AND_ASSIGN
@@ -70,8 +71,7 @@
         MODE_RT_ONLY,
     };
 
-    TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContext)
-            : mode(mode), prepareTextures(mode == MODE_FULL), canvasContext(canvasContext) {}
+    TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContext);
 
     TraversalMode mode;
     // TODO: Remove this? Currently this is used to signal to stop preparing
@@ -93,6 +93,8 @@
 
     bool updateWindowPositions = false;
 
+    int disableForceDark;
+
     struct Out {
         bool hasFunctors = false;
         // This is only updated if evaluateAnimations is true
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 9f82d0f..6cf04bf 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -458,29 +458,22 @@
         mStagingCache.dirty = false;
     }
 
-    SkPaint tmpPaint;
-    SkPaint* paint = updatePaint(&tmpPaint, &mStagingProperties);
+    SkPaint paint;
+    getPaintFor(&paint, mStagingProperties);
     outCanvas->drawBitmap(*mStagingCache.bitmap, 0, 0, mStagingCache.bitmap->width(),
                           mStagingCache.bitmap->height(), mStagingProperties.getBounds().left(),
                           mStagingProperties.getBounds().top(),
                           mStagingProperties.getBounds().right(),
-                          mStagingProperties.getBounds().bottom(), paint);
+                          mStagingProperties.getBounds().bottom(), &paint);
 }
 
-SkPaint* Tree::getPaint() {
-    return updatePaint(&mPaint, &mProperties);
-}
-
-// Update the given paint with alpha and color filter. Return nullptr if no color filter is
-// specified and root alpha is 1. Otherwise, return updated paint.
-SkPaint* Tree::updatePaint(SkPaint* outPaint, TreeProperties* prop) {
+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) {
-        outPaint->setColorFilter(sk_ref_sp(prop->getColorFilter()));
-        outPaint->setAlpha(prop->getRootAlpha() * 255);
+    if (prop.getColorFilter() != nullptr) {
+        outPaint->setColorFilter(sk_ref_sp(prop.getColorFilter()));
     }
-    return outPaint;
+    outPaint->setAlpha(prop.getRootAlpha() * 255);
 }
 
 Bitmap& Tree::getBitmapUpdateIfDirty() {
@@ -553,11 +546,15 @@
     mAtlasKey = INVALID_ATLAS_KEY;
 }
 
-void Tree::draw(SkCanvas* canvas, const SkRect& bounds) {
+void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) {
+    // Update the paint for any animatable properties
+    SkPaint paint = inPaint;
+    paint.setAlpha(mProperties.getRootAlpha() * 255);
+
     SkRect src;
     sk_sp<SkSurface> vdSurface = mCache.getSurface(&src);
     if (vdSurface) {
-        canvas->drawImageRect(vdSurface->makeImageSnapshot().get(), src, bounds, getPaint(),
+        canvas->drawImageRect(vdSurface->makeImageSnapshot().get(), src, bounds, &paint,
                               SkCanvas::kFast_SrcRectConstraint);
     } else {
         // Handle the case when VectorDrawableAtlas has been destroyed, because of memory pressure.
@@ -570,7 +567,7 @@
         int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth());
         int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight());
         canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds,
-                               getPaint(), SkCanvas::kFast_SrcRectConstraint);
+                               &paint, SkCanvas::kFast_SrcRectConstraint);
         mCache.clear();
         markDirty();
     }
@@ -620,6 +617,80 @@
     }
 }
 
+class MinMaxAverage {
+public:
+    void add(float sample) {
+        if (mCount == 0) {
+            mMin = sample;
+            mMax = sample;
+        } else {
+            mMin = std::min(mMin, sample);
+            mMax = std::max(mMax, sample);
+        }
+        mTotal += sample;
+        mCount++;
+    }
+
+    float average() { return mTotal / mCount; }
+
+    float min() { return mMin; }
+
+    float max() { return mMax; }
+
+    float delta() { return mMax - mMin; }
+
+private:
+    float mMin = 0.0f;
+    float mMax = 0.0f;
+    float mTotal = 0.0f;
+    int mCount = 0;
+};
+
+BitmapPalette Tree::computePalette() {
+    // TODO Cache this and share the code with Bitmap.cpp
+
+    ATRACE_CALL();
+
+    // TODO: This calculation of converting to HSV & tracking min/max is probably overkill
+    // Experiment with something simpler since we just want to figure out if it's "color-ful"
+    // and then the average perceptual lightness.
+
+    MinMaxAverage hue, saturation, value;
+    int sampledCount = 0;
+
+    // Sample a grid of 100 pixels to get an overall estimation of the colors in play
+    mRootNode->forEachFillColor([&](SkColor color) {
+        if (SkColorGetA(color) < 75) {
+            return;
+        }
+        sampledCount++;
+        float hsv[3];
+        SkColorToHSV(color, hsv);
+        hue.add(hsv[0]);
+        saturation.add(hsv[1]);
+        value.add(hsv[2]);
+    });
+
+    if (sampledCount == 0) {
+        ALOGV("VectorDrawable is mostly translucent");
+        return BitmapPalette::Unknown;
+    }
+
+    ALOGV("samples = %d, hue [min = %f, max = %f, avg = %f]; saturation [min = %f, max = %f, avg = "
+          "%f]; value [min = %f, max = %f, avg = %f]",
+          sampledCount, hue.min(), hue.max(), hue.average(), saturation.min(), saturation.max(),
+          saturation.average(), value.min(), value.max(), value.average());
+
+    if (hue.delta() <= 20 && saturation.delta() <= .1f) {
+        if (value.average() >= .5f) {
+            return BitmapPalette::Light;
+        } else {
+            return BitmapPalette::Dark;
+        }
+    }
+    return BitmapPalette::Unknown;
+}
+
 };  // namespace VectorDrawable
 
 };  // namespace uirenderer
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index af0ae05..9c0bb16 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -120,6 +120,8 @@
     virtual void syncProperties() = 0;
     virtual void setAntiAlias(bool aa) = 0;
 
+    virtual void forEachFillColor(const std::function<void(SkColor)>& func) const { }
+
 protected:
     std::string mName;
     PropertyChangedListener* mPropertyChangedListener = nullptr;
@@ -349,6 +351,9 @@
         }
     }
     virtual void setAntiAlias(bool aa) { mAntiAlias = aa; }
+    void forEachFillColor(const std::function<void(SkColor)>& func) const override {
+        func(mStagingProperties.getFillColor());
+    }
 
 protected:
     const SkPath& getUpdatedPath(bool useStagingData, SkPath* tempStagingPath) override;
@@ -480,6 +485,12 @@
         }
     }
 
+    void forEachFillColor(const std::function<void(SkColor)>& func) const override {
+        for (auto& child : mChildren) {
+            child->forEachFillColor(func);
+        }
+    }
+
 private:
     GroupProperties mProperties = GroupProperties(this);
     GroupProperties mStagingProperties = GroupProperties(this);
@@ -495,8 +506,8 @@
 
     // Copy properties from the tree and use the give node as the root node
     Tree(const Tree* copy, Group* rootNode) : Tree(rootNode) {
-        mStagingProperties.syncAnimatableProperties(*copy->stagingProperties());
-        mStagingProperties.syncNonAnimatableProperties(*copy->stagingProperties());
+        mStagingProperties.syncAnimatableProperties(copy->stagingProperties());
+        mStagingProperties.syncNonAnimatableProperties(copy->stagingProperties());
     }
     // Draws the VD onto a bitmap cache, then the bitmap cache will be rendered onto the input
     // canvas. Returns the number of pixels needed for the bitmap cache.
@@ -506,7 +517,6 @@
 
     Bitmap& getBitmapUpdateIfDirty();
     void setAllowCaching(bool allowCaching) { mAllowCaching = allowCaching; }
-    SkPaint* getPaint();
     void syncProperties() {
         if (mStagingProperties.mNonAnimatablePropertiesDirty) {
             mCache.dirty |= (mProperties.mNonAnimatableProperties.viewportWidth !=
@@ -618,7 +628,7 @@
     };
     void onPropertyChanged(TreeProperties* prop);
     TreeProperties* mutateStagingProperties() { return &mStagingProperties; }
-    const TreeProperties* stagingProperties() const { return &mStagingProperties; }
+    const TreeProperties& stagingProperties() const { return mStagingProperties; }
 
     // This should only be called from animations on RT
     TreeProperties* mutateProperties() { return &mProperties; }
@@ -636,7 +646,10 @@
      * Draws VD cache into a canvas. This should always be called from RT and it works with Skia
      * pipelines only.
      */
-    void draw(SkCanvas* canvas, const SkRect& bounds);
+    void draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& paint);
+
+    void getPaintFor(SkPaint* outPaint, const TreeProperties &props) const;
+    BitmapPalette computePalette();
 
     /**
      * Draws VD into a GPU backed surface.
@@ -680,7 +693,6 @@
         skiapipeline::AtlasKey mAtlasKey = INVALID_ATLAS_KEY;
     };
 
-    SkPaint* updatePaint(SkPaint* outPaint, TreeProperties* prop);
     bool allocateBitmapIfNeeded(Cache& cache, int width, int height);
     bool canReuseBitmap(Bitmap*, int width, int height);
     void updateBitmapCache(Bitmap& outCache, bool useStagingData);
@@ -696,8 +708,6 @@
     TreeProperties mProperties = TreeProperties(this);
     TreeProperties mStagingProperties = TreeProperties(this);
 
-    SkPaint mPaint;
-
     Cache mStagingCache;
     Cache mCache;
 
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index 8a44b8b..f0aa35a 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -106,7 +106,7 @@
     Snapshot decodeNextFrame();
     Snapshot reset();
 
-    size_t byteSize() const { return sizeof(this) + mBytesUsed; }
+    size_t byteSize() const { return sizeof(*this) + mBytesUsed; }
 
 protected:
     virtual void onDraw(SkCanvas* canvas) override;
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 440620a..b04194f 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));
 }
 
@@ -230,8 +231,6 @@
             mPixelStorage.hardware.buffer = nullptr;
             break;
     }
-
-    android::uirenderer::renderthread::RenderProxy::onBitmapDestroyed(getStableID());
 }
 
 bool Bitmap::hasHardwareMipMap() const {
@@ -330,15 +329,6 @@
     if (image->colorSpace() != nullptr && !image->colorSpace()->isSRGB()) {
         *outputColorFilter = SkToSRGBColorFilter::Make(image->refColorSpace());
     }
-
-    // TODO: Move this to the canvas (or other?) layer where we have the target lightness
-    // mode and can selectively do the right thing.
-    //    if (palette() != BitmapPalette::Unknown && uirenderer::Properties::forceDarkMode) {
-    //        SkHighContrastConfig config;
-    //        config.fInvertStyle = SkHighContrastConfig::InvertStyle::kInvertLightness;
-    //        *outputColorFilter =
-    //        SkHighContrastFilter::Make(config)->makeComposed(*outputColorFilter);
-    //    }
     return image;
 }
 
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 170335d..238c764 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -34,6 +34,8 @@
     Hardware,
 };
 
+// TODO: Find a better home for this. It's here because hwui/Bitmap is exported and CanvasTransform
+// isn't, but cleanup should be done
 enum class BitmapPalette {
     Unknown,
     Light,
@@ -62,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/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 78b64b2..3890513 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -132,7 +132,6 @@
     mChildFunctors.clear();
     mChildNodes.clear();
 
-    projectionReceiveIndex = -1;
     allocator.~LinearAllocator();
     new (&allocator) LinearAllocator();
 }
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 4c78539..ac7bb7b 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -49,9 +49,6 @@
  */
 class SkiaDisplayList {
 public:
-    // index of DisplayListOp restore, after which projected descendants should be drawn
-    int projectionReceiveIndex = -1;
-
     size_t getUsedSize() { return allocator.usedSize(); }
 
     ~SkiaDisplayList() {
@@ -96,6 +93,8 @@
      */
     bool hasVectorDrawables() const { return !mVectorDrawables.empty(); }
 
+    bool hasText() const { return mDisplayList.hasText(); }
+
     /**
      * Attempts to reset and reuse this DisplayList.
      *
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 3b1ebd6..d401b38 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -21,6 +21,7 @@
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 #include "hwui/Bitmap.h"
+#include "private/hwui/DrawGlInfo.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/EglManager.h"
 #include "renderthread/Frame.h"
@@ -43,7 +44,13 @@
 namespace skiapipeline {
 
 SkiaOpenGLPipeline::SkiaOpenGLPipeline(RenderThread& thread)
-        : SkiaPipeline(thread), mEglManager(thread.eglManager()) {}
+        : SkiaPipeline(thread), mEglManager(thread.eglManager()) {
+    thread.renderState().registerContextCallback(this);
+}
+
+SkiaOpenGLPipeline::~SkiaOpenGLPipeline() {
+    mRenderThread.renderState().removeContextCallback(this);
+}
 
 MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() {
     // TODO: Figure out why this workaround is needed, see b/13913604
@@ -135,6 +142,13 @@
     return new DeferredLayerUpdater(mRenderThread.renderState());
 }
 
+void SkiaOpenGLPipeline::onContextDestroyed() {
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mEglManager.destroySurface(mEglSurface);
+        mEglSurface = EGL_NO_SURFACE;
+    }
+}
+
 void SkiaOpenGLPipeline::onStop() {
     if (mEglManager.isCurrent(mEglSurface)) {
         mEglManager.makeCurrent(EGL_NO_SURFACE);
@@ -153,6 +167,12 @@
         mEglSurface = mEglManager.createSurface(surface, colorMode);
     }
 
+    if (colorMode == ColorMode::SRGB) {
+        mSurfaceColorType = SkColorType::kN32_SkColorType;
+    } else if (colorMode == ColorMode::WideColorGamut) {
+        mSurfaceColorType = SkColorType::kRGBA_F16_SkColorType;
+    }
+
     if (mEglSurface != EGL_NO_SURFACE) {
         const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
         mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
@@ -170,14 +190,6 @@
     return CC_LIKELY(mEglManager.hasEglContext());
 }
 
-SkColorType SkiaOpenGLPipeline::getSurfaceColorType() const {
-    return mEglManager.getSurfaceColorType();
-}
-
-sk_sp<SkColorSpace> SkiaOpenGLPipeline::getSurfaceColorSpace() {
-    return mEglManager.getSurfaceColorSpace();
-}
-
 void SkiaOpenGLPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
     DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
     if (thread.eglManager().hasEglContext()) {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index fbdf313..4ab3541 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -18,6 +18,8 @@
 
 #include "SkiaPipeline.h"
 
+#include "renderstate/RenderState.h"
+
 namespace android {
 
 class Bitmap;
@@ -25,10 +27,10 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-class SkiaOpenGLPipeline : public SkiaPipeline {
+class SkiaOpenGLPipeline : public SkiaPipeline, public IGpuContextCallback {
 public:
     SkiaOpenGLPipeline(renderthread::RenderThread& thread);
-    virtual ~SkiaOpenGLPipeline() {}
+    virtual ~SkiaOpenGLPipeline();
 
     renderthread::MakeCurrentResult makeCurrent() override;
     renderthread::Frame getFrame() override;
@@ -45,11 +47,12 @@
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
-    SkColorType getSurfaceColorType() const override;
-    sk_sp<SkColorSpace> getSurfaceColorSpace() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
 
+protected:
+    void onContextDestroyed() override;
+
 private:
     renderthread::EglManager& mEglManager;
     EGLSurface mEglSurface = EGL_NO_SURFACE;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 7f8abb8..2dfe7c7 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -200,10 +200,6 @@
     return false;
 }
 
-void SkiaPipeline::destroyLayer(RenderNode* node) {
-    node->setLayerSurface(nullptr);
-}
-
 void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
     GrContext* context = thread.getGrContext();
     if (context) {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index b78dea1..42a411a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -48,14 +48,15 @@
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
                              ErrorHandler* errorHandler) override;
 
+    SkColorType getSurfaceColorType() const { return mSurfaceColorType; }
+    sk_sp<SkColorSpace> getSurfaceColorSpace() override { return mSurfaceColorSpace; }
+
     void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
                      const std::vector<sp<RenderNode>>& nodes, bool opaque,
                      const Rect& contentDrawBounds, sk_sp<SkSurface> surface);
 
     std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; }
 
-    static void destroyLayer(RenderNode* node);
-
     static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
 
     void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
@@ -108,6 +109,8 @@
     void dumpResourceCacheUsage() const;
 
     renderthread::RenderThread& mRenderThread;
+    SkColorType mSurfaceColorType;
+    sk_sp<SkColorSpace> mSurfaceColorSpace;
 
 private:
     void renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 3c281e7..3fa73a4 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -113,8 +113,6 @@
     // use staging property, since recording on UI thread
     if (renderNode->stagingProperties().isProjectionReceiver()) {
         mDisplayList->mProjectionReceiver = &renderNodeDrawable;
-        // set projectionReceiveIndex so that RenderNode.hasProjectionReceiver returns true
-        mDisplayList->projectionReceiveIndex = mDisplayList->mChildNodes.size() - 1;
     }
 }
 
@@ -132,25 +130,8 @@
     drawDrawable(functorDrawable);
 }
 
-class VectorDrawable : public SkDrawable {
-public:
-    VectorDrawable(VectorDrawableRoot* tree)
-            : mRoot(tree)
-            , mBounds(tree->stagingProperties()->getBounds()) {}
-
-protected:
-    virtual SkRect onGetBounds() override { return mBounds; }
-    virtual void onDraw(SkCanvas* canvas) override {
-        mRoot->draw(canvas, mBounds);
-    }
-
-private:
-    sp<VectorDrawableRoot> mRoot;
-    SkRect mBounds;
-};
-
 void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
-    drawDrawable(mDisplayList->allocateDrawable<VectorDrawable>(tree));
+    mRecorder.drawVectorDrawable(tree);
     mDisplayList->mVectorDrawables.push_back(tree);
 }
 
@@ -196,7 +177,7 @@
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
     sk_sp<SkColorFilter> colorFilter;
     sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
-    mRecorder.drawImage(image, left, top, filterBitmap(paint, std::move(colorFilter)));
+    mRecorder.drawImage(image, left, top, filterBitmap(paint, std::move(colorFilter)), bitmap.palette());
     // if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
     // it is not safe to store a raw SkImage pointer, because the image object will be destroyed
     // when this function ends.
@@ -211,7 +192,7 @@
 
     sk_sp<SkColorFilter> colorFilter;
     sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
-    mRecorder.drawImage(image, 0, 0, filterBitmap(paint, std::move(colorFilter)));
+    mRecorder.drawImage(image, 0, 0, filterBitmap(paint, std::move(colorFilter)), bitmap.palette());
     if (!bitmap.isImmutable() && image.get() && !image->unique()) {
         mDisplayList->mMutableImages.push_back(image.get());
     }
@@ -226,7 +207,7 @@
     sk_sp<SkColorFilter> colorFilter;
     sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
     mRecorder.drawImageRect(image, srcRect, dstRect, filterBitmap(paint, std::move(colorFilter)),
-                            SkCanvas::kFast_SrcRectConstraint);
+                            SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
     if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty() &&
         !dstRect.isEmpty()) {
         mDisplayList->mMutableImages.push_back(image.get());
@@ -264,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/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index e34f160..2ca110f 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -123,8 +123,13 @@
     }
 
     if (surface) {
-        // TODO: handle color mode
-        mVkSurface = mVkManager.createSurface(surface);
+        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;
@@ -138,14 +143,6 @@
     return CC_LIKELY(mVkManager.hasVkContext());
 }
 
-SkColorType SkiaVulkanPipeline::getSurfaceColorType() const {
-    return mVkManager.getSurfaceColorType();
-}
-
-sk_sp<SkColorSpace> SkiaVulkanPipeline::getSurfaceColorSpace() {
-    return mVkManager.getSurfaceColorSpace();
-}
-
 void SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
     VkFunctorDrawable::vkInvokeFunctor(functor);
 }
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 6e723a8..14c0d69 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -43,8 +43,6 @@
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
-    SkColorType getSurfaceColorType() const override;
-    sk_sp<SkColorSpace> getSurfaceColorSpace() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
     static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index b524bcb..fad9440 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -14,91 +14,28 @@
  * limitations under the License.
  */
 #include "renderstate/RenderState.h"
-#include <GpuMemoryTracker.h>
-#include "DeferredLayerUpdater.h"
-#include "Snapshot.h"
 
-#include "renderthread/CanvasContext.h"
-#include "renderthread/EglManager.h"
-#include "utils/GLUtils.h"
-
-#include <algorithm>
-
-#include <ui/ColorSpace.h>
+#include "renderthread/RenderThread.h"
+#include "GpuMemoryTracker.h"
 
 namespace android {
 namespace uirenderer {
 
-RenderState::RenderState(renderthread::RenderThread& thread)
-        : mRenderThread(thread), mViewportWidth(0), mViewportHeight(0), mFramebuffer(0) {
+RenderState::RenderState(renderthread::RenderThread& thread) : mRenderThread(thread) {
     mThreadId = pthread_self();
 }
 
-RenderState::~RenderState() {
-}
-
 void RenderState::onContextCreated() {
     GpuMemoryTracker::onGpuContextCreated();
 }
 
 void RenderState::onContextDestroyed() {
-    destroyLayersInUpdater();
+    for(auto callback : mContextCallbacks) {
+        callback->onContextDestroyed();
+    }
     GpuMemoryTracker::onGpuContextDestroyed();
 }
 
-GrContext* RenderState::getGrContext() const {
-    return mRenderThread.getGrContext();
-}
-
-void RenderState::onBitmapDestroyed(uint32_t pixelRefId) {
-    // DEAD CODE
-}
-
-void RenderState::setViewport(GLsizei width, GLsizei height) {
-    mViewportWidth = width;
-    mViewportHeight = height;
-    glViewport(0, 0, mViewportWidth, mViewportHeight);
-}
-
-void RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) {
-    *outWidth = mViewportWidth;
-    *outHeight = mViewportHeight;
-}
-
-void RenderState::bindFramebuffer(GLuint fbo) {
-    if (mFramebuffer != fbo) {
-        mFramebuffer = fbo;
-        glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
-    }
-}
-
-GLuint RenderState::createFramebuffer() {
-    GLuint ret;
-    glGenFramebuffers(1, &ret);
-    return ret;
-}
-
-void RenderState::deleteFramebuffer(GLuint fbo) {
-    if (mFramebuffer == fbo) {
-        // GL defines that deleting the currently bound FBO rebinds FBO 0.
-        // Reflect this in our cached value.
-        mFramebuffer = 0;
-    }
-    glDeleteFramebuffers(1, &fbo);
-}
-
-void RenderState::debugOverdraw(bool enable, bool clear) {
-    // DEAD CODE
-}
-
-static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
-    layerUpdater->destroyLayer();
-}
-
-void RenderState::destroyLayersInUpdater() {
-    std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater);
-}
-
 void RenderState::postDecStrong(VirtualLightRefBase* object) {
     if (pthread_equal(mThreadId, pthread_self())) {
         object->decStrong(nullptr);
@@ -111,13 +48,5 @@
 // Render
 ///////////////////////////////////////////////////////////////////////////////
 
-void RenderState::dump() {
-    // DEAD CODE
-}
-
-renderthread::RenderThread& RenderState::getRenderThread() {
-    return mRenderThread;
-}
-
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index f39aa4b..ff5d02f 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -18,29 +18,26 @@
 
 #include "utils/Macros.h"
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <private/hwui/DrawGlInfo.h>
-#include <ui/Region.h>
-#include <utils/Functor.h>
-#include <utils/Mutex.h>
 #include <utils/RefBase.h>
 #include <set>
 
-class GrContext;
-
 namespace android {
 namespace uirenderer {
 
 class Layer;
-class DeferredLayerUpdater;
 
 namespace renderthread {
 class CacheManager;
-class CanvasContext;
 class RenderThread;
 }
 
+class IGpuContextCallback {
+public:
+    virtual void onContextDestroyed() = 0;
+protected:
+    virtual ~IGpuContextCallback() {}
+};
+
 // wrapper of Caches for users to migrate to.
 class RenderState {
     PREVENT_COPY_AND_ASSIGN(RenderState);
@@ -48,66 +45,30 @@
     friend class renderthread::CacheManager;
 
 public:
-    void onContextCreated();
-    void onContextDestroyed();
-
-    void onBitmapDestroyed(uint32_t pixelRefId);
-
-    void setViewport(GLsizei width, GLsizei height);
-    void getViewport(GLsizei* outWidth, GLsizei* outHeight);
-
-    void bindFramebuffer(GLuint fbo);
-    GLuint getFramebuffer() { return mFramebuffer; }
-    GLuint createFramebuffer();
-    void deleteFramebuffer(GLuint fbo);
-
-    void debugOverdraw(bool enable, bool clear);
+    void registerContextCallback(IGpuContextCallback* cb) { mContextCallbacks.insert(cb); }
+    void removeContextCallback(IGpuContextCallback* cb) { mContextCallbacks.erase(cb); }
 
     void registerLayer(Layer* layer) { mActiveLayers.insert(layer); }
     void unregisterLayer(Layer* layer) { mActiveLayers.erase(layer); }
 
-    void registerCanvasContext(renderthread::CanvasContext* context) {
-        mRegisteredContexts.insert(context);
-    }
-
-    void unregisterCanvasContext(renderthread::CanvasContext* context) {
-        mRegisteredContexts.erase(context);
-    }
-
-    void registerDeferredLayerUpdater(DeferredLayerUpdater* layerUpdater) {
-        mActiveLayerUpdaters.insert(layerUpdater);
-    }
-
-    void unregisterDeferredLayerUpdater(DeferredLayerUpdater* layerUpdater) {
-        mActiveLayerUpdaters.erase(layerUpdater);
-    }
-
     // TODO: This system is a little clunky feeling, this could use some
     // more thinking...
     void postDecStrong(VirtualLightRefBase* object);
 
-    GrContext* getGrContext() const;
-
-    void dump();
-
-    renderthread::RenderThread& getRenderThread();
+    renderthread::RenderThread& getRenderThread() const { return mRenderThread; }
 
 private:
-    void destroyLayersInUpdater();
-
     explicit RenderState(renderthread::RenderThread& thread);
-    ~RenderState();
+    ~RenderState() {}
+
+    // Context notifications are only to be triggered by renderthread::RenderThread
+    void onContextCreated();
+    void onContextDestroyed();
+
+    std::set<IGpuContextCallback*> mContextCallbacks;
+    std::set<Layer*> mActiveLayers;
 
     renderthread::RenderThread& mRenderThread;
-
-    std::set<Layer*> mActiveLayers;
-    std::set<DeferredLayerUpdater*> mActiveLayerUpdaters;
-    std::set<renderthread::CanvasContext*> mRegisteredContexts;
-
-    GLsizei mViewportWidth;
-    GLsizei mViewportHeight;
-    GLuint mFramebuffer;
-
     pthread_t mThreadId;
 };
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index ea6a851..92a749f 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -27,7 +27,6 @@
 #include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/SkiaPipeline.h"
 #include "pipeline/skia/SkiaVulkanPipeline.h"
-#include "renderstate/RenderState.h"
 #include "utils/GLUtils.h"
 #include "utils/TimeUtils.h"
 #include "../Properties.h"
@@ -76,10 +75,6 @@
     return nullptr;
 }
 
-void CanvasContext::destroyLayer(RenderNode* node) {
-    skiapipeline::SkiaPipeline::destroyLayer(node);
-}
-
 void CanvasContext::invokeFunctor(const RenderThread& thread, Functor* functor) {
     ATRACE_CALL();
     auto renderType = Properties::getRenderPipelineType();
@@ -113,13 +108,11 @@
         , mRenderPipeline(std::move(renderPipeline)) {
     rootRenderNode->makeRoot();
     mRenderNodes.emplace_back(rootRenderNode);
-    mRenderThread.renderState().registerCanvasContext(this);
     mProfiler.setDensity(mRenderThread.mainDisplayInfo().density);
 }
 
 CanvasContext::~CanvasContext() {
     destroy();
-    mRenderThread.renderState().unregisterCanvasContext(this);
     for (auto& node : mRenderNodes) {
         node->clearRoot();
     }
@@ -151,8 +144,7 @@
 
     mNativeSurface = std::move(surface);
 
-    // TODO(b/111436479) Introduce a way for app to specify DisplayColorGamut mode.
-    ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::Legacy;
+    ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
     bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode);
 
     mFrameNumber = -1;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 8448788..2307ee4 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -96,12 +96,6 @@
      */
     void unpinImages() { mRenderPipeline->unpinImages(); }
 
-    /**
-     * Destroy any layers that have been attached to the provided RenderNode removing
-     * any state that may have been set during createOrUpdateLayer().
-     */
-    static void destroyLayer(RenderNode* node);
-
     static void invokeFunctor(const RenderThread& thread, Functor* functor);
 
     static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
@@ -188,6 +182,23 @@
         mFrameCompleteCallbacks.push_back(std::move(func));
     }
 
+    void setForceDark(bool enable) {
+        mUseForceDark = enable;
+    }
+
+    bool useForceDark() {
+        // The force-dark override has the highest priority, followed by the disable setting
+        // for the feature as a whole, followed last by whether or not this context has had
+        // force dark set (typically automatically done via UIMode)
+        if (Properties::forceDarkMode) {
+            return true;
+        }
+        if (!Properties::enableForceDarkSupport) {
+            return false;
+        }
+        return mUseForceDark;
+    }
+
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
                   IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -234,6 +245,7 @@
 
     bool mOpaque;
     bool mWideColorGamut = false;
+    bool mUseForceDark = false;
     LightInfo mLightInfo;
     LightGeometry mLightGeometry = {{0, 0, 0}, 0};
 
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 0cb23e5..d4ffddd 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -126,17 +126,6 @@
     createContext();
     createPBufferSurface();
     makeCurrent(mPBufferSurface, nullptr, /* force */ true);
-
-    mSurfaceColorGamut = DataSpaceToColorGamut(
-        static_cast<android_dataspace>(DeviceInfo::get()->getTargetDataSpace()));
-
-    LOG_ALWAYS_FATAL_IF(mSurfaceColorGamut == SkColorSpace::kDCIP3_D65_Gamut &&
-                        !EglExtensions.displayP3, "EGL doesn't support Display P3.");
-
-    mSurfaceColorType = PixelFormatToColorType(
-        static_cast<android_pixel_format>(DeviceInfo::get()->getTargetPixelFormat()));
-    mSurfaceColorSpace = DataSpaceToColorSpace(
-        static_cast<android_dataspace>(DeviceInfo::get()->getTargetDataSpace()));
 }
 
 void EglManager::initExtensions() {
@@ -309,21 +298,13 @@
         if (wideColorGamut) {
             attribs[1] = EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT;
         } else {
-            if (mSurfaceColorGamut == SkColorSpace::kDCIP3_D65_Gamut) {
-                attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_EXT;
-            } else {
-                attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
-            }
+            attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
         }
 #else
         if (wideColorGamut) {
             attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
         } else {
-            if (mSurfaceColorGamut == SkColorSpace::kDCIP3_D65_Gamut) {
-                attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_EXT;
-            } else {
-                attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
-            }
+            attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
         }
 #endif
     }
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index e97228c..55c81d4 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -78,9 +78,6 @@
     // Depending on installed extensions, the result is either Android native fence or EGL fence.
     status_t createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, sp<Fence>& nativeFence);
 
-    SkColorType getSurfaceColorType() const { return mSurfaceColorType; }
-    sk_sp<SkColorSpace> getSurfaceColorSpace() { return mSurfaceColorSpace; }
-
 private:
 
     void initExtensions();
@@ -95,9 +92,6 @@
     EGLContext mEglContext;
     EGLSurface mPBufferSurface;
     EGLSurface mCurrentSurface;
-    SkColorSpace::Gamut mSurfaceColorGamut;
-    SkColorType mSurfaceColorType;
-    sk_sp<SkColorSpace> mSurfaceColorSpace;
 
     enum class SwapBehavior {
         Discard,
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 0297c9c..4972554 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -43,15 +43,8 @@
 enum class MakeCurrentResult { AlreadyCurrent, Failed, Succeeded };
 
 enum class ColorMode {
-    // Legacy means HWUI will produce buffer with whatever platform prefers
-    // HWUI to produce, however, HWUI doesn't accurately convert color from
-    // source color space to destination color space, instead HWUI will take
-    // the pixel value directly and interpret it destination color space.
-    Legacy,
-    // DisplayColorGamut means HWUI will produce buffer with whatever platform
-    // prefers HWUI to produce and accurately convert color from source color
-    // space to destination color space.
-    DisplayColorGamut,
+    // SRGB means HWUI will produce buffer in SRGB color space.
+    SRGB,
     // WideColorGamut means HWUI would support rendering scRGB non-linear into
     // a signed buffer with enough range to support the wide color gamut of the
     // display.
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 7a5348a..54219b5 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -298,6 +298,12 @@
     });
 }
 
+void RenderProxy::setForceDark(bool enable) {
+    mRenderThread.queue().post([this, enable]() {
+        mContext->setForceDark(enable);
+    });
+}
+
 int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
                                  SkBitmap* bitmap) {
     auto& thread = RenderThread::getInstance();
@@ -345,13 +351,6 @@
     }
 }
 
-void RenderProxy::onBitmapDestroyed(uint32_t pixelRefId) {
-    if (!RenderThread::hasInstance()) return;
-    RenderThread& thread = RenderThread::getInstance();
-    thread.queue().post(
-            [&thread, pixelRefId]() { thread.renderState().onBitmapDestroyed(pixelRefId); });
-}
-
 void RenderProxy::disableVsync() {
     Properties::disableVsync = true;
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 969ad00..d29fcc4 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -119,7 +119,7 @@
 
     ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer);
     ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
-    ANDROID_API long getDroppedFrameReportCount();
+    ANDROID_API void setForceDark(bool enable);
 
     ANDROID_API static int copySurfaceInto(sp<Surface>& surface, int left, int top, int right,
                                            int bottom, SkBitmap* bitmap);
@@ -127,8 +127,6 @@
 
     static int copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap);
 
-    static void onBitmapDestroyed(uint32_t pixelRefId);
-
     ANDROID_API static void disableVsync();
 
     static void repackVectorDrawableAtlas();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index a5dcc72..207673c1 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -177,7 +177,6 @@
         return;
     }
     mEglManager->initialize();
-    renderState().onContextCreated();
 
 #ifdef HWUI_GLES_WRAP_ENABLED
     debug::GlesDriver* driver = debug::GlesDriver::get();
@@ -201,7 +200,6 @@
 void RenderThread::destroyGlContext() {
     if (mEglManager->hasEglContext()) {
         setGrContext(nullptr);
-        renderState().onContextDestroyed();
         mEglManager->destroy();
     }
 }
@@ -243,10 +241,12 @@
 void RenderThread::setGrContext(sk_sp<GrContext> context) {
     mCacheManager->reset(context);
     if (mGrContext) {
+        mRenderState->onContextDestroyed();
         mGrContext->releaseResourcesAndAbandonContext();
     }
     mGrContext = std::move(context);
     if (mGrContext) {
+        mRenderState->onContextCreated();
         DeviceInfo::setMaxTextureSize(mGrContext->maxRenderTargetSize());
     }
 }
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 4881172..9e435a5 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -16,6 +16,8 @@
 
 #include "VulkanManager.h"
 
+#include <private/gui/SyncFeatures.h>
+
 #include "Properties.h"
 #include "RenderThread.h"
 #include "renderstate/RenderState.h"
@@ -39,9 +41,12 @@
 VulkanManager::VulkanManager(RenderThread& thread) : mRenderThread(thread) {}
 
 void VulkanManager::destroy() {
-    mRenderThread.renderState().onContextDestroyed();
     mRenderThread.setGrContext(nullptr);
 
+    // We don't need to explicitly free the command buffer since it automatically gets freed when we
+    // delete the VkCommandPool below.
+    mDummyCB = VK_NULL_HANDLE;
+
     if (VK_NULL_HANDLE != mCommandPool) {
         mDestroyCommandPool(mDevice, mCommandPool, nullptr);
         mCommandPool = VK_NULL_HANDLE;
@@ -73,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;
@@ -128,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);
@@ -159,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);
@@ -227,6 +240,11 @@
     grExtensions.init(getProc, mInstance, mPhysicalDevice, instanceExtensions.size(),
             instanceExtensions.data(), deviceExtensions.size(), deviceExtensions.data());
 
+    if (!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)) {
+        this->destroy();
+        return false;
+    }
+
     memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2));
     features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
     features.pNext = nullptr;
@@ -314,6 +332,8 @@
     GET_DEV_PROC(DeviceWaitIdle);
     GET_DEV_PROC(CreateSemaphore);
     GET_DEV_PROC(DestroySemaphore);
+    GET_DEV_PROC(ImportSemaphoreFdKHR);
+    GET_DEV_PROC(GetSemaphoreFdKHR);
     GET_DEV_PROC(CreateFence);
     GET_DEV_PROC(DestroyFence);
     GET_DEV_PROC(WaitForFences);
@@ -385,6 +405,14 @@
                 &mCommandPool);
         SkASSERT(VK_SUCCESS == res);
     }
+    LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE);
+
+    if (!setupDummyCommandBuffer()) {
+        this->destroy();
+        return;
+    }
+    LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE);
+
 
     mGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue);
 
@@ -401,8 +429,6 @@
     if (Properties::enablePartialUpdates && Properties::useBufferAge) {
         mSwapBehavior = SwapBehavior::BufferAge;
     }
-
-    mRenderThread.renderState().onContextCreated();
 }
 
 // Returns the next BackbufferInfo to use for the next draw. The function will make sure all
@@ -470,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
@@ -600,7 +624,8 @@
         VulkanSurface::ImageInfo& imageInfo = surface->mImageInfos[i];
         imageInfo.mSurface = SkSurface::MakeFromBackendRenderTarget(
                 mRenderThread.getGrContext(), backendRT, kTopLeft_GrSurfaceOrigin,
-                kRGBA_8888_SkColorType, nullptr, &props);
+                surface->mColorMode == ColorMode::WideColorGamut ? kRGBA_F16_SkColorType
+                : kRGBA_8888_SkColorType, nullptr, &props);
     }
 
     SkASSERT(mCommandPool != VK_NULL_HANDLE);
@@ -715,38 +740,28 @@
                     ? VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
                     : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
 
-    // Pick our surface format. For now, just make sure it matches our sRGB request:
-    VkFormat surfaceFormat = VK_FORMAT_UNDEFINED;
+    VkFormat surfaceFormat = VK_FORMAT_R8G8B8A8_UNORM;
     VkColorSpaceKHR colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
-
-    bool wantSRGB = false;
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
-    wantSRGB = true;
-#endif
+    if (surface->mColorMode == ColorMode::WideColorGamut) {
+        surfaceFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
+        colorSpace = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT;
+    }
+    bool foundSurfaceFormat = false;
     for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
-        // We are assuming we can get either R8G8B8A8_UNORM or R8G8B8A8_SRGB
-        VkFormat desiredFormat = wantSRGB ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
-        if (desiredFormat == surfaceFormats[i].format) {
-            surfaceFormat = surfaceFormats[i].format;
-            colorSpace = surfaceFormats[i].colorSpace;
-        }
-    }
-
-    if (VK_FORMAT_UNDEFINED == surfaceFormat) {
-        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.
-    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];
+        if (surfaceFormat == surfaceFormats[i].format
+                && colorSpace == surfaceFormats[i].colorSpace) {
+            foundSurfaceFormat = true;
             break;
         }
     }
 
+    if (!foundSurfaceFormat) {
+        return false;
+    }
+
+    // FIFO is always available and will match what we do on GL so just pick that here.
+    VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
+
     VkSwapchainCreateInfoKHR swapchainCreateInfo;
     memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
     swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
@@ -794,14 +809,14 @@
     return true;
 }
 
-VulkanSurface* VulkanManager::createSurface(ANativeWindow* window) {
+VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode) {
     initialize();
 
     if (!window) {
         return nullptr;
     }
 
-    VulkanSurface* surface = new VulkanSurface();
+    VulkanSurface* surface = new VulkanSurface(colorMode);
 
     VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
     memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
@@ -832,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;
     }
@@ -899,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
@@ -979,19 +996,176 @@
     return surface->mCurrentTime - lastUsed;
 }
 
+bool VulkanManager::setupDummyCommandBuffer() {
+    if (mDummyCB != VK_NULL_HANDLE) {
+        return true;
+    }
+
+    VkCommandBufferAllocateInfo commandBuffersInfo;
+    memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo));
+    commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    commandBuffersInfo.pNext = nullptr;
+    commandBuffersInfo.commandPool = mCommandPool;
+    commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    commandBuffersInfo.commandBufferCount = 1;
+
+    VkResult err = mAllocateCommandBuffers(mDevice, &commandBuffersInfo, &mDummyCB);
+    if (err != VK_SUCCESS) {
+        // It is probably unnecessary to set this back to VK_NULL_HANDLE, but we set it anyways to
+        // make sure the driver didn't set a value and then return a failure.
+        mDummyCB = VK_NULL_HANDLE;
+        return false;
+    }
+
+    VkCommandBufferBeginInfo beginInfo;
+    memset(&beginInfo, 0, sizeof(VkCommandBufferBeginInfo));
+    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
+
+    mBeginCommandBuffer(mDummyCB, &beginInfo);
+    mEndCommandBuffer(mDummyCB);
+    return true;
+}
+
 status_t VulkanManager::fenceWait(sp<Fence>& fence) {
-    //TODO: Insert a wait on fence command into the Vulkan command buffer.
-    // Block CPU on the fence.
-    status_t err = fence->waitForever("VulkanManager::fenceWait");
-    if (err != NO_ERROR) {
-        ALOGE("VulkanManager::fenceWait: error waiting for fence: %d", err);
-        return err;
+    if (!hasVkContext()) {
+        ALOGE("VulkanManager::fenceWait: VkDevice not initialized");
+        return INVALID_OPERATION;
+    }
+
+    if (SyncFeatures::getInstance().useWaitSync() &&
+        SyncFeatures::getInstance().useNativeFenceSync()) {
+        // Block GPU on the fence.
+        int fenceFd = fence->dup();
+        if (fenceFd == -1) {
+            ALOGE("VulkanManager::fenceWait: error dup'ing fence fd: %d", errno);
+            return -errno;
+        }
+
+        VkSemaphoreCreateInfo semaphoreInfo;
+        semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+        semaphoreInfo.pNext = nullptr;
+        semaphoreInfo.flags = 0;
+        VkSemaphore semaphore;
+        VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore);
+        if (VK_SUCCESS != err) {
+            ALOGE("Failed to create import semaphore, err: %d", err);
+            return UNKNOWN_ERROR;
+        }
+        VkImportSemaphoreFdInfoKHR importInfo;
+        importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
+        importInfo.pNext = nullptr;
+        importInfo.semaphore = semaphore;
+        importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT;
+        importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
+        importInfo.fd = fenceFd;
+
+        err = mImportSemaphoreFdKHR(mDevice, &importInfo);
+        if (VK_SUCCESS != err) {
+            ALOGE("Failed to import semaphore, err: %d", err);
+            return UNKNOWN_ERROR;
+        }
+
+        LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE);
+
+        VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+
+        VkSubmitInfo submitInfo;
+        memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+        submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submitInfo.waitSemaphoreCount = 1;
+        // Wait to make sure aquire semaphore set above has signaled.
+        submitInfo.pWaitSemaphores = &semaphore;
+        submitInfo.pWaitDstStageMask = &waitDstStageFlags;
+        submitInfo.commandBufferCount = 1;
+        submitInfo.pCommandBuffers = &mDummyCB;
+        submitInfo.signalSemaphoreCount = 0;
+
+        mQueueSubmit(mGraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
+
+        // On Android when we import a semaphore, it is imported using temporary permanence. That
+        // means as soon as we queue the semaphore for a wait it reverts to its previous permanent
+        // state before importing. This means it will now be in an idle state with no pending
+        // signal or wait operations, so it is safe to immediately delete it.
+        mDestroySemaphore(mDevice, semaphore, nullptr);
+    } else {
+        // Block CPU on the fence.
+        status_t err = fence->waitForever("VulkanManager::fenceWait");
+        if (err != NO_ERROR) {
+            ALOGE("VulkanManager::fenceWait: error waiting for fence: %d", err);
+            return err;
+        }
     }
     return OK;
 }
 
 status_t VulkanManager::createReleaseFence(sp<Fence>& nativeFence) {
-    //TODO: Create a fence that is signaled, when all the pending Vulkan commands are flushed.
+    if (!hasVkContext()) {
+        ALOGE("VulkanManager::createReleaseFence: VkDevice not initialized");
+        return INVALID_OPERATION;
+    }
+
+    if (SyncFeatures::getInstance().useFenceSync()) {
+        ALOGE("VulkanManager::createReleaseFence: Vk backend doesn't support non-native fences");
+        return INVALID_OPERATION;
+    }
+
+    if (!SyncFeatures::getInstance().useNativeFenceSync()) {
+        return OK;
+    }
+
+    VkExportSemaphoreCreateInfo exportInfo;
+    exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
+    exportInfo.pNext = nullptr;
+    exportInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
+
+    VkSemaphoreCreateInfo semaphoreInfo;
+    semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    semaphoreInfo.pNext = &exportInfo;
+    semaphoreInfo.flags = 0;
+    VkSemaphore semaphore;
+    VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore);
+    if (VK_SUCCESS != err) {
+        ALOGE("VulkanManager::createReleaseFence: Failed to create semaphore");
+        return INVALID_OPERATION;
+    }
+
+    LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE);
+
+    VkSubmitInfo submitInfo;
+    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submitInfo.waitSemaphoreCount = 0;
+    submitInfo.pWaitSemaphores = nullptr;
+    submitInfo.pWaitDstStageMask = nullptr;
+    submitInfo.commandBufferCount = 1;
+    submitInfo.pCommandBuffers = &mDummyCB;
+    submitInfo.signalSemaphoreCount = 1;
+    submitInfo.pSignalSemaphores = &semaphore;
+
+    mQueueSubmit(mGraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
+
+    VkSemaphoreGetFdInfoKHR getFdInfo;
+    getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
+    getFdInfo.pNext = nullptr;
+    getFdInfo.semaphore = semaphore;
+    getFdInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
+
+    int fenceFd = 0;
+
+    err = mGetSemaphoreFdKHR(mDevice, &getFdInfo, &fenceFd);
+    if (VK_SUCCESS != err) {
+        ALOGE("VulkanManager::createReleaseFence: Failed to get semaphore Fd");
+        return INVALID_OPERATION;
+    }
+    nativeFence = new Fence(fenceFd);
+
+    // Exporting a semaphore with copy transference via vkGetSemahporeFdKHR, has the same effect of
+    // destroying the semaphore and creating a new one with the same handle, and the payloads
+    // ownership is move to the Fd we created. Thus the semahpore is in a state that we can delete
+    // it and we don't need to wait on the command buffer we submitted to finish.
+    mDestroySemaphore(mDevice, semaphore, nullptr);
+
     return OK;
 }
 
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 7a539ae..6702649 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -26,6 +26,7 @@
 #include <ui/Fence.h>
 #include <utils/StrongPointer.h>
 #include <vk/GrVkBackendContext.h>
+#include "IRenderPipeline.h"
 
 class GrVkExtensions;
 
@@ -37,7 +38,7 @@
 
 class VulkanSurface {
 public:
-    VulkanSurface() {}
+    VulkanSurface(ColorMode colorMode) : mColorMode(colorMode) {}
 
     sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; }
 
@@ -73,6 +74,7 @@
     VkImage* mImages = nullptr;
     ImageInfo* mImageInfos;
     uint16_t mCurrentTime = 0;
+    ColorMode mColorMode;
 };
 
 // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue,
@@ -90,7 +92,7 @@
 
     // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new
     // VulkanSurface object which is returned.
-    VulkanSurface* createSurface(ANativeWindow* window);
+    VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode);
 
     // Destroy the VulkanSurface and all associated vulkan objects.
     void destroySurface(VulkanSurface* surface);
@@ -118,10 +120,6 @@
     // Creates a fence that is signaled, when all the pending Vulkan commands are flushed.
     status_t createReleaseFence(sp<Fence>& nativeFence);
 
-    // TODO(b/115636873): Handle composition preference.
-    SkColorType getSurfaceColorType() const { return SkColorType::kN32_SkColorType; }
-    sk_sp<SkColorSpace> getSurfaceColorSpace() { return SkColorSpace::MakeSRGB(); }
-
 private:
     friend class RenderThread;
 
@@ -139,6 +137,8 @@
 
     VulkanSurface::BackbufferInfo* getAvailableBackbuffer(VulkanSurface* surface);
 
+    bool setupDummyCommandBuffer();
+
     // simple wrapper class that exists only to initialize a pointer to NULL
     template <typename FNPTR_TYPE>
     class VkPtr {
@@ -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;
@@ -199,6 +200,8 @@
 
     VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore;
     VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore;
+    VkPtr<PFN_vkImportSemaphoreFdKHR> mImportSemaphoreFdKHR;
+    VkPtr<PFN_vkGetSemaphoreFdKHR> mGetSemaphoreFdKHR;
     VkPtr<PFN_vkCreateFence> mCreateFence;
     VkPtr<PFN_vkDestroyFence> mDestroyFence;
     VkPtr<PFN_vkWaitForFences> mWaitForFences;
@@ -216,6 +219,8 @@
     VkQueue mPresentQueue = VK_NULL_HANDLE;
     VkCommandPool mCommandPool = VK_NULL_HANDLE;
 
+    VkCommandBuffer mDummyCB = VK_NULL_HANDLE;
+
     enum class SwapBehavior {
         Discard,
         BufferAge,
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index c35f512..a00b8db 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -24,6 +24,7 @@
 #include <Snapshot.h>
 #include <hwui/Bitmap.h>
 #include <pipeline/skia/SkiaRecordingCanvas.h>
+#include <private/hwui/DrawGlInfo.h>
 #include <renderstate/RenderState.h>
 #include <renderthread/RenderThread.h>
 
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index 5e5d134..cdf31da 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -382,3 +382,13 @@
                           SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
+
+RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
+    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+    EXPECT_FALSE(pipeline->isSurfaceReady());
+    EXPECT_TRUE(pipeline->setSurface((Surface*)0x01, SwapBehavior::kSwap_default, ColorMode::SRGB));
+    EXPECT_TRUE(pipeline->isSurfaceReady());
+    renderThread.destroyGlContext();
+    EXPECT_FALSE(pipeline->isSurfaceReady());
+}
+
diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp
index 9f71e91..3fb6a31 100644
--- a/libs/hwui/utils/Color.cpp
+++ b/libs/hwui/utils/Color.cpp
@@ -57,21 +57,6 @@
     return false;
 }
 
-SkColorType PixelFormatToColorType(android_pixel_format pixelFormat) {
-    switch (pixelFormat) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-            return SkColorType::kN32_SkColorType;
-        case HAL_PIXEL_FORMAT_RGBA_FP16:
-            return SkColorType::kRGBA_F16_SkColorType;
-        case HAL_PIXEL_FORMAT_RGBA_1010102:
-            return SkColorType::kRGBA_1010102_SkColorType;
-        default:
-            ALOGW("Unsupported pixel format: %d, return kN32 by default", pixelFormat);
-            return SkColorType::kN32_SkColorType;
-    }
-}
-
 android::PixelFormat ColorTypeToPixelFormat(SkColorType colorType) {
     switch (colorType) {
         case kRGBA_8888_SkColorType:
@@ -92,30 +77,6 @@
     }
 }
 
-SkColorSpace::Gamut DataSpaceToColorGamut(android_dataspace dataSpace) {
-    switch (dataSpace & HAL_DATASPACE_STANDARD_MASK) {
-        case HAL_DATASPACE_STANDARD_BT709:
-            return SkColorSpace::kSRGB_Gamut;
-        case HAL_DATASPACE_STANDARD_BT2020:
-            return SkColorSpace::kRec2020_Gamut;
-        case HAL_DATASPACE_STANDARD_DCI_P3:
-            return SkColorSpace::kDCIP3_D65_Gamut;
-        case HAL_DATASPACE_STANDARD_ADOBE_RGB:
-            return SkColorSpace::kAdobeRGB_Gamut;
-        case HAL_DATASPACE_STANDARD_UNSPECIFIED:
-        case HAL_DATASPACE_STANDARD_BT601_625:
-        case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
-        case HAL_DATASPACE_STANDARD_BT601_525:
-        case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
-        case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
-        case HAL_DATASPACE_STANDARD_BT470M:
-        case HAL_DATASPACE_STANDARD_FILM:
-        default:
-            ALOGW("Unsupported Gamut: %d, return SRGB gamut by default", dataSpace);
-            return SkColorSpace::kSRGB_Gamut;
-    }
-}
-
 sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) {
 
     SkColorSpace::Gamut gamut;
diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h
index e935a0d..4daccda 100644
--- a/libs/hwui/utils/Color.h
+++ b/libs/hwui/utils/Color.h
@@ -115,12 +115,8 @@
 // returns true for sRGB, gamma 2.2 and Display P3 for instance
 bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace);
 
-SkColorType PixelFormatToColorType(android_pixel_format pixelFormat);
-
 android::PixelFormat ColorTypeToPixelFormat(SkColorType colorType);
 
-SkColorSpace::Gamut DataSpaceToColorGamut(android_dataspace dataSpace);
-
 sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace);
 
 struct Lab {
diff --git a/libs/services/include/android/os/StatsLogEventWrapper.h b/libs/services/include/android/os/StatsLogEventWrapper.h
index 255619c..f60c338 100644
--- a/libs/services/include/android/os/StatsLogEventWrapper.h
+++ b/libs/services/include/android/os/StatsLogEventWrapper.h
@@ -25,6 +25,63 @@
 namespace android {
 namespace os {
 
+/**
+ * A wrapper for a union type to contain multiple types of values.
+ *
+ */
+struct StatsLogValue {
+  // Keep in sync with FieldValue.h
+  enum STATS_LOG_VALUE_TYPE {
+    UNKNOWN = 0,
+    INT = 1,
+    LONG = 2,
+    FLOAT = 3,
+    DOUBLE = 4,
+    STRING = 5,
+    STORAGE = 6
+  };
+
+  StatsLogValue() : type(UNKNOWN) {}
+
+  StatsLogValue(int32_t v) {
+    int_value = v;
+    type = INT;
+  }
+
+  StatsLogValue(int64_t v) {
+    long_value = v;
+    type = LONG;
+  }
+
+  StatsLogValue(float v) {
+    float_value = v;
+    type = FLOAT;
+  }
+
+  StatsLogValue(double v) {
+    double_value = v;
+    type = DOUBLE;
+  }
+
+  StatsLogValue(const std::string& v) {
+    str_value = v;
+    type = STRING;
+  }
+
+  void setType(STATS_LOG_VALUE_TYPE t) { type = t; }
+
+  union {
+    int32_t int_value;
+    int64_t long_value;
+    float float_value;
+    double double_value;
+  };
+  std::string str_value;
+  std::vector<uint8_t> storage_value;
+
+  STATS_LOG_VALUE_TYPE type;
+};
+
 // Represents a parcelable object. Only used to send data from Android OS to statsd.
 class StatsLogEventWrapper : public android::Parcelable {
  public:
@@ -36,8 +93,22 @@
 
   android::status_t readFromParcel(const android::Parcel* in);
 
-  // These are public for ease of conversion.
-  std::vector<uint8_t> bytes;
+  int getTagId() const { return mTagId; }
+
+  int64_t getElapsedRealTimeNs() const { return mElapsedRealTimeNs; }
+
+  int64_t getWallClockTimeNs() const { return mWallClockTimeNs; }
+
+  std::vector<StatsLogValue> getElements() const { return mElements; }
+
+ private:
+  int mTagId;
+
+  int64_t mElapsedRealTimeNs;
+
+  int64_t mWallClockTimeNs;
+
+  std::vector<StatsLogValue> mElements;
 };
 } // Namespace os
 } // Namespace android
diff --git a/libs/services/src/os/StatsLogEventWrapper.cpp b/libs/services/src/os/StatsLogEventWrapper.cpp
index 8b3aa9a..a1a6d9f 100644
--- a/libs/services/src/os/StatsLogEventWrapper.cpp
+++ b/libs/services/src/os/StatsLogEventWrapper.cpp
@@ -32,13 +32,73 @@
 StatsLogEventWrapper::StatsLogEventWrapper(){};
 
 status_t StatsLogEventWrapper::writeToParcel(Parcel* out) const {
-    out->writeByteVector(bytes);
-    return ::android::NO_ERROR;
+  // Implement me if desired. We don't currently use this.
+  ALOGE(
+      "Cannot do c++ StatsLogEventWrapper.writeToParcel(); it is not "
+      "implemented.");
+  (void)out;  // To prevent compile error of unused parameter 'in'
+  return UNKNOWN_ERROR;
 };
 
 status_t StatsLogEventWrapper::readFromParcel(const Parcel* in) {
-    in->readByteVector(&bytes);
-    return ::android::NO_ERROR;
+  status_t res = OK;
+  if (in == NULL) {
+    ALOGE("statsd received parcel argument was NULL.");
+    return BAD_VALUE;
+  }
+  if ((res = in->readInt32(&mTagId)) != OK) {
+    ALOGE("statsd could not read tagId from parcel");
+    return res;
+  }
+  if ((res = in->readInt64(&mElapsedRealTimeNs)) != OK) {
+    ALOGE("statsd could not read elapsed real time from parcel");
+    return res;
+  }
+  if ((res = in->readInt64(&mWallClockTimeNs)) != OK) {
+    ALOGE("statsd could not read wall clock time from parcel");
+    return res;
+  }
+  int dataSize = 0;
+  if ((res = in->readInt32(&dataSize)) != OK) {
+    ALOGE("statsd could not read data size from parcel");
+    return res;
+  }
+  if (mTagId <= 0 || mElapsedRealTimeNs <= 0 || mWallClockTimeNs <= 0 ||
+      dataSize <= 0) {
+    ALOGE("statsd received invalid parcel");
+    return BAD_VALUE;
+  }
+
+  for (int i = 0; i < dataSize; i++) {
+    int type = in->readInt32();
+    switch (type) {
+      case StatsLogValue::INT:
+        mElements.push_back(StatsLogValue(in->readInt32()));
+        break;
+      case StatsLogValue::LONG:
+        mElements.push_back(StatsLogValue(in->readInt64()));
+        break;
+      case StatsLogValue::STRING:
+        mElements.push_back(
+            StatsLogValue(std::string(String8(in->readString16()).string())));
+        break;
+      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);
+        in->readByteVector(&(mElements.back().storage_value));
+        break;
+      default:
+        ALOGE("unrecognized data type: %d", type);
+        return BAD_TYPE;
+    }
+  }
+  return NO_ERROR;
 };
 
 } // Namespace os
diff --git a/location/java/android/location/Address.java b/location/java/android/location/Address.java
index 335ad5e..83f05c2 100644
--- a/location/java/android/location/Address.java
+++ b/location/java/android/location/Address.java
@@ -363,7 +363,7 @@
      * or null if it is unknown.
      *
      * @throws IllegalStateException if this Address has not been assigned
-     * a latitude.
+     * a phone number.
      */
     public String getPhone() {
         return mPhone;
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index a6099be..74eb445 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -21,9 +21,9 @@
 
 /**
  * A class indicating the application criteria for selecting a
- * location provider.  Providers maybe ordered according to accuracy,
- * power usage, ability to report altitude, speed,
- * and bearing, and monetary cost.
+ * location provider. Providers may be ordered according to accuracy,
+ * power usage, ability to report altitude, speed, bearing, and monetary
+ * cost.
  */
 public class Criteria implements Parcelable {
     /**
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index 447195d..b09335c 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -18,4 +18,5 @@
     name: "com.android.location.provider",
     srcs: ["java/**/*.java"],
     api_packages: ["com.android.location.provider"],
+    metalava_enabled: false,
 }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 85eac4b..c074cce 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4607,7 +4607,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/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/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index ed4da22..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,
@@ -336,7 +336,7 @@
  *
  * <table border="0" cellspacing="0" cellpadding="0">
  * <tr><td>Method Name </p></td>
- *     <td>Valid Sates </p></td>
+ *     <td>Valid States </p></td>
  *     <td>Invalid States </p></td>
  *     <td>Comments </p></td></tr>
  * <tr><td>attachAuxEffect </p></td>
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 89827bc..8665f28 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -30,6 +30,8 @@
 import android.view.Surface;
 import android.view.SurfaceHolder;
 
+import dalvik.system.CloseGuard;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
@@ -45,425 +47,202 @@
 
 /**
  * @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
                                             , 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();
     }
 
@@ -512,7 +291,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 +326,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,
@@ -1108,12 +904,9 @@
 
     /**
      * Sets playback rate using {@link PlaybackParams}. The object sets its internal
-     * PlaybackParams to the input, except that the object remembers previous speed
-     * when input speed is zero. This allows the object to resume at previous speed
-     * when play() is called. Calling it before the object is prepared does not change
-     * the object state. After the object is prepared, calling it with zero speed is
-     * equivalent to calling pause(). After the object is prepared, calling it with
-     * non-zero speed is equivalent to calling play().
+     * PlaybackParams to the input. This allows the object to resume at previous speed
+     * when play() is called. Speed of zero is not allowed. Calling it does not change
+     * the object state.
      *
      * @param params the playback params.
      */
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index 6187900..678cb9a 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -36,8 +36,6 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
 import android.os.Process;
@@ -55,12 +53,8 @@
 
 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 libcore.io.Streams;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -82,10 +76,10 @@
 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;
 
 /**
@@ -107,7 +101,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
@@ -147,6 +140,9 @@
     @GuardedBy("mTaskLock")
     private Task mCurrentTask;
 
+    @GuardedBy("this")
+    private boolean mReleased;
+
     /**
      * Default constructor.
      * <p>When done with the MediaPlayer2Impl, you should call  {@link #close()},
@@ -161,7 +157,6 @@
 
         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++.
@@ -199,9 +194,8 @@
      */
     @Override
     public void close() {
-        synchronized (mGuard) {
-            release();
-        }
+        super.close();
+        release();
     }
 
     /**
@@ -253,21 +247,6 @@
             void process() {
                 stayAwake(false);
 
-                // TODO: remove this block when native code allows prepared -> pause
-                // and sends MEDIA_INFO_DATA_SOURCE_START when pipeline is created.
-                if (getState() == PLAYER_STATE_PREPARED) {
-                    final DataSourceDesc dsd;
-                    synchronized (mSrcLock) {
-                        dsd = mCurrentDSD;
-                    }
-                    synchronized (mEventCbLock) {
-                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                            cb.first.execute(() -> cb.second.onInfo(
-                                    MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
-                        }
-                    }
-                }
-
                 _pause();
             }
         });
@@ -285,7 +264,10 @@
         addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
             @Override
             void process() {
-                // TODO: switch to next data source and play
+                if (getState() == PLAYER_STATE_PLAYING) {
+                    pause();
+                }
+                playNextDataSource();
             }
         });
     }
@@ -346,19 +328,14 @@
                     final String msg = "Cannot set AudioAttributes to null";
                     throw new IllegalArgumentException(msg);
                 }
-                Parcel pattributes = Parcel.obtain();
-                attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
-                setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
-                pattributes.recycle();
+                setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, attributes);
             }
         });
     }
 
     @Override
     public @NonNull AudioAttributes getAudioAttributes() {
-        Parcel pattributes = getParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES);
-        AudioAttributes attributes = AudioAttributes.CREATOR.createFromParcel(pattributes);
-        pattributes.recycle();
+        AudioAttributes attributes = (AudioAttributes) getParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES);
         return attributes;
     }
 
@@ -372,7 +349,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);
@@ -398,7 +375,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);
@@ -572,12 +549,13 @@
         addTask(new Task(CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED, false) {
             @Override
             void process() {
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onCommandLabelReached(
-                                MediaPlayer2Impl.this, label));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onCommandLabelReached(
+                                MediaPlayer2Impl.this, label);
                     }
-                }
+                });
             }
         });
     }
@@ -711,7 +689,7 @@
 
     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:
@@ -995,12 +973,13 @@
         }
 
         if (!hasNextDSD) {
-            synchronized (mEventCbLock) {
-                for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                    cb.first.execute(() -> cb.second.onInfo(
-                            MediaPlayer2Impl.this, null, MEDIA_INFO_DATA_SOURCE_LIST_END, 0));
+            sendEvent(new EventNotifier() {
+                @Override
+                public void notify(EventCallback callback) {
+                    callback.onInfo(
+                            MediaPlayer2Impl.this, null, MEDIA_INFO_DATA_SOURCE_LIST_END, 0);
                 }
-            }
+            });
         }
     }
 
@@ -1310,7 +1289,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);
             }
         });
@@ -1374,7 +1353,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);
             }
         });
@@ -1407,7 +1386,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);
             }
         });
@@ -1597,9 +1576,9 @@
      * @param value value of the parameter to be set.
      * @return true if the parameter is set successfully, false otherwise
      */
-    private native boolean setParameter(int key, Parcel value);
+    private native boolean setParameter(int key, Object value);
 
-    private native Parcel getParameter(int key);
+    private native Object getParameter(int key);
 
 
     /**
@@ -2464,15 +2443,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) {
@@ -2495,6 +2473,7 @@
         resetDrmState();
 
         _release();
+        mReleased = true;
     }
 
     private native void _release();
@@ -2583,12 +2562,13 @@
                 }
 
                 if (dsd != null) {
-                    synchronized (mEventCbLock) {
-                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                            cb.first.execute(() -> cb.second.onInfo(
-                                    mMediaPlayer, dsd, MEDIA_INFO_PREPARED, 0));
+                    sendEvent(new EventNotifier() {
+                        @Override
+                        public void notify(EventCallback callback) {
+                            callback.onInfo(
+                                    mMediaPlayer, dsd, MEDIA_INFO_PREPARED, 0);
                         }
-                    }
+                    });
                 }
 
                 synchronized (mSrcLock) {
@@ -2636,12 +2616,13 @@
 
                     // notifying the client outside the lock
                     if (drmInfo != null) {
-                        synchronized (mEventCbLock) {
-                            for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
-                                cb.first.execute(() -> cb.second.onDrmInfo(
-                                        mMediaPlayer, dsd, drmInfo));
+                        sendDrmEvent(new DrmEventNotifier() {
+                            @Override
+                            public void notify(DrmEventCallback callback) {
+                                callback.onDrmInfo(
+                                        mMediaPlayer, dsd, drmInfo);
                             }
-                        }
+                        });
                     }
                 } else {
                     Log.w(TAG, "MEDIA_DRM_INFO msg.obj of unexpected type " + msg.obj);
@@ -2652,12 +2633,13 @@
             case MEDIA_PLAYBACK_COMPLETE:
             {
                 if (isCurrentSrcId) {
-                    synchronized (mEventCbLock) {
-                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                            cb.first.execute(() -> cb.second.onInfo(
-                                    mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
+                    sendEvent(new EventNotifier() {
+                        @Override
+                        public void notify(EventCallback callback) {
+                            callback.onInfo(
+                                    mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0);
                         }
-                    }
+                    });
                     stayAwake(false);
 
                     synchronized (mSrcLock) {
@@ -2695,13 +2677,13 @@
             case MEDIA_BUFFERING_UPDATE:
             {
                 final int percent = msg.arg1;
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, dsd, MEDIA_INFO_BUFFERING_UPDATE,
-                                percent));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onInfo(
+                                mMediaPlayer, dsd, MEDIA_INFO_BUFFERING_UPDATE, percent);
                     }
-                }
+                });
 
                 synchronized (mSrcLock) {
                     if (isCurrentSrcId) {
@@ -2740,26 +2722,33 @@
             {
                 final int width = msg.arg1;
                 final int height = msg.arg2;
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onVideoSizeChanged(
-                                mMediaPlayer, dsd, width, height));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onVideoSizeChanged(
+                                mMediaPlayer, dsd, width, height);
                     }
-                }
+                });
                 return;
             }
 
             case MEDIA_ERROR:
             {
                 Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onError(
-                                mMediaPlayer, dsd, what, extra));
-                        cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onError(
+                                mMediaPlayer, dsd, what, extra);
                     }
-                }
+                });
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onInfo(
+                                mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0);
+                    }
+                });
                 stayAwake(false);
                 return;
             }
@@ -2799,12 +2788,13 @@
                         break;
                 }
 
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, dsd, what, extra));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onInfo(
+                                mMediaPlayer, dsd, what, extra);
                     }
-                }
+                });
 
                 if (msg.arg1 == MEDIA_INFO_DATA_SOURCE_START) {
                     if (isCurrentSrcId) {
@@ -2841,12 +2831,13 @@
                     text = null;
                 }
 
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onTimedText(
-                                mMediaPlayer, dsd, text));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onTimedText(
+                                mMediaPlayer, dsd, text);
                     }
-                }
+                });
                 return;
             }
 
@@ -2866,12 +2857,13 @@
                             in.next().getInt64Value(),  // startTimeUs
                             in.next().getInt64Value(),  // durationUs
                             in.next().getBytesValue().toByteArray());  // data
-                    synchronized (mEventCbLock) {
-                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                            cb.first.execute(() -> cb.second.onSubtitleData(
-                                    mMediaPlayer, dsd, data));
+                    sendEvent(new EventNotifier() {
+                        @Override
+                        public void notify(EventCallback callback) {
+                            callback.onSubtitleData(
+                                    mMediaPlayer, dsd, data);
                         }
-                    }
+                    });
                 }
                 return;
             }
@@ -2895,12 +2887,13 @@
                     data = null;
                 }
 
-                synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onTimedMetaDataAvailable(
-                                mMediaPlayer, dsd, data));
+                sendEvent(new EventNotifier() {
+                    @Override
+                    public void notify(EventCallback callback) {
+                        callback.onTimedMetaDataAvailable(
+                                mMediaPlayer, dsd, data);
                     }
-                }
+                });
                 return;
             }
 
@@ -3033,6 +3026,46 @@
         }
     }
 
+    public static void checkArgument(boolean expression, String errorMessage) {
+        if (!expression) {
+            throw new IllegalArgumentException(errorMessage);
+        }
+    }
+
+    private void sendEvent(final EventNotifier notifier) {
+        synchronized (mEventCbLock) {
+            try {
+                for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    cb.first.execute(() -> notifier.notify(cb.second));
+                }
+            } catch (RejectedExecutionException e) {
+                // The executor has been shut down.
+                Log.w(TAG, "The executor has been shut down. Ignoring event.");
+            }
+        }
+    }
+
+    private void sendDrmEvent(final DrmEventNotifier notifier) {
+        synchronized (mDrmEventCbLock) {
+            try {
+                for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
+                    cb.first.execute(() -> notifier.notify(cb.second));
+                }
+            } catch (RejectedExecutionException e) {
+                // The executor has been shut down.
+                Log.w(TAG, "The executor has been shut down. Ignoring drm event.");
+            }
+        }
+    }
+
+    private interface EventNotifier {
+        void notify(EventCallback callback);
+    }
+
+    private interface DrmEventNotifier {
+        void notify(DrmEventCallback callback);
+    }
+
     // Modular DRM begin
 
     /**
@@ -3283,12 +3316,13 @@
 
         // if finished successfully without provisioning, call the callback outside the lock
         if (allDoneWithoutProvisioning) {
-            synchronized (mDrmEventCbLock) {
-                for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
-                    cb.first.execute(() -> cb.second.onDrmPrepared(
-                            this, mCurrentDSD, PREPARE_DRM_STATUS_SUCCESS));
+            sendDrmEvent(new DrmEventNotifier() {
+                @Override
+                public void notify(DrmEventCallback callback) {
+                    callback.onDrmPrepared(
+                            MediaPlayer2Impl.this, mCurrentDSD, PREPARE_DRM_STATUS_SUCCESS);
                 }
-            }
+            });
         }
 
     }
@@ -3641,7 +3675,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);
 
@@ -3649,7 +3683,7 @@
                       supportedSchemes[i]);
             }
 
-            Log.v(TAG, "DrmInfoImpl() Parcel psshsize: " + pssh.length +
+            Log.v(TAG, "DrmInfoImpl() psshsize: " + pssh.length +
                   " supportedDRMsCount: " + supportedDRMsCount);
         }
 
@@ -3774,7 +3808,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 {
@@ -3914,7 +3948,7 @@
                     connection.setReadTimeout(TIMEOUT_MS);
 
                     connection.connect();
-                    response = Streams.readFully(connection.getInputStream());
+                    response = readInputStreamFully(connection.getInputStream());
 
                     Log.v(TAG, "HandleProvisioninig: Thread run: response " +
                             response.length + " " + response);
@@ -3968,12 +4002,13 @@
                 } // synchronized
 
                 // calling the callback outside the lock
-                synchronized (mDrmEventCbLock) {
-                    for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onDrmPrepared(
-                                mediaPlayer, mCurrentDSD, status));
+                sendDrmEvent(new DrmEventNotifier() {
+                    @Override
+                    public void notify(DrmEventCallback callback) {
+                        callback.onDrmPrepared(
+                                mediaPlayer, mCurrentDSD, status);
                     }
-                }
+                });
             } else {   // blocking mode already has the lock
 
                 // continuing with prepareDrm
@@ -3993,6 +4028,29 @@
             finished = true;
         }   // run()
 
+        /**
+         * Returns a byte[] containing the remainder of 'in', closing it when done.
+         */
+        private byte[] readInputStreamFully(InputStream in) throws IOException {
+            try {
+                return readInputStreamFullyNoClose(in);
+            } finally {
+                in.close();
+            }
+        }
+
+        /**
+         * Returns a byte[] containing the remainder of 'in'.
+         */
+        private byte[] readInputStreamFullyNoClose(InputStream in) throws IOException {
+            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int count;
+            while ((count = in.read(buffer)) != -1) {
+                bytes.write(buffer, 0, count);
+            }
+            return bytes.toByteArray();
+        }
     }   // ProvisioningThread
 
     private int HandleProvisioninig(UUID uuid) {
@@ -4628,16 +4686,17 @@
 
         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;
             }
-            synchronized (mEventCbLock) {
-                for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                    cb.first.execute(() -> cb.second.onCallCompleted(
-                            MediaPlayer2Impl.this, mDSD, mMediaCallType, status));
+            sendEvent(new EventNotifier() {
+                @Override
+                public void notify(EventCallback callback) {
+                    callback.onCallCompleted(
+                            MediaPlayer2Impl.this, mDSD, mMediaCallType, status);
                 }
-            }
+            });
         }
     };
 
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 0ff2d8f..c537945 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -160,8 +160,9 @@
 
     public static final String SCANNED_BUILD_PREFS_NAME = "MediaScanBuild";
     public static final String LAST_INTERNAL_SCAN_FINGERPRINT = "lastScanFingerprint";
-    private static final String SYSTEM_SOUNDS_DIR = "/system/media/audio";
-    private static final String PRODUCT_SOUNDS_DIR = "/product/media/audio";
+    private static final String SYSTEM_SOUNDS_DIR = Environment.getRootDirectory() + "/media/audio";
+    private static final String OEM_SOUNDS_DIR = Environment.getOemDirectory() + "/media/audio";
+    private static final String PRODUCT_SOUNDS_DIR = Environment.getProductDirectory() + "/media/audio";
     private static String sLastInternalScanFingerprint;
 
     private static final String[] ID3_GENRES = {
@@ -1193,6 +1194,9 @@
         if (path.startsWith(SYSTEM_SOUNDS_DIR + ALARMS_DIR)
                 || path.startsWith(SYSTEM_SOUNDS_DIR + RINGTONES_DIR)
                 || path.startsWith(SYSTEM_SOUNDS_DIR + NOTIFICATIONS_DIR)
+                || path.startsWith(OEM_SOUNDS_DIR + ALARMS_DIR)
+                || path.startsWith(OEM_SOUNDS_DIR + RINGTONES_DIR)
+                || path.startsWith(OEM_SOUNDS_DIR + NOTIFICATIONS_DIR)
                 || path.startsWith(PRODUCT_SOUNDS_DIR + ALARMS_DIR)
                 || path.startsWith(PRODUCT_SOUNDS_DIR + RINGTONES_DIR)
                 || path.startsWith(PRODUCT_SOUNDS_DIR + NOTIFICATIONS_DIR)) {
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/jni/Android.bp b/media/jni/Android.bp
index 7681cc3..3870124 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -88,8 +88,6 @@
     name: "libmedia2_jni",
 
     srcs: [
-        "android_media_Media2HTTPConnection.cpp",
-        "android_media_Media2HTTPService.cpp",
         "android_media_Media2DataSource.cpp",
         "android_media_MediaMetricsJNI.cpp",
         "android_media_MediaPlayer2.cpp",
@@ -142,6 +140,7 @@
         "libstagefright_player2",
         "libstagefright_rtsp",
         "libstagefright_timedtext2",
+        "libmedia2_jni_core",
     ],
 
     group_static_libs: true,
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_Media2HTTPConnection.cpp b/media/jni/android_media_Media2HTTPConnection.cpp
deleted file mode 100644
index d02ee06..0000000
--- a/media/jni/android_media_Media2HTTPConnection.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Media2HTTPConnection-JNI"
-#include <utils/Log.h>
-
-#include <mediaplayer2/JavaVMHelper.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <nativehelper/ScopedLocalRef.h>
-
-#include "android_media_Media2HTTPConnection.h"
-#include "android_util_Binder.h"
-
-#include "log/log.h"
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-static const size_t kBufferSize = 32768;
-
-JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
-    mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
-    CHECK(mMedia2HTTPConnectionObj != NULL);
-
-    ScopedLocalRef<jclass> media2HTTPConnectionClass(
-            env, env->GetObjectClass(mMedia2HTTPConnectionObj));
-    CHECK(media2HTTPConnectionClass.get() != NULL);
-
-    mConnectMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "connect",
-            "(Ljava/lang/String;Ljava/lang/String;)Z");
-    CHECK(mConnectMethod != NULL);
-
-    mDisconnectMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "disconnect",
-            "()V");
-    CHECK(mDisconnectMethod != NULL);
-
-    mReadAtMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "readAt",
-            "(J[BI)I");
-    CHECK(mReadAtMethod != NULL);
-
-    mGetSizeMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getSize",
-            "()J");
-    CHECK(mGetSizeMethod != NULL);
-
-    mGetMIMETypeMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getMIMEType",
-            "()Ljava/lang/String;");
-    CHECK(mGetMIMETypeMethod != NULL);
-
-    mGetUriMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getUri",
-            "()Ljava/lang/String;");
-    CHECK(mGetUriMethod != NULL);
-
-    ScopedLocalRef<jbyteArray> tmp(
-        env, env->NewByteArray(kBufferSize));
-    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
-    CHECK(mByteArrayObj != NULL);
-}
-
-JMedia2HTTPConnection::~JMedia2HTTPConnection() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
-    env->DeleteGlobalRef(mByteArrayObj);
-}
-
-bool JMedia2HTTPConnection::connect(
-        const char *uri, const KeyedVector<String8, String8> *headers) {
-    String8 tmp("");
-    if (headers != NULL) {
-        for (size_t i = 0; i < headers->size(); ++i) {
-            tmp.append(headers->keyAt(i));
-            tmp.append(String8(": "));
-            tmp.append(headers->valueAt(i));
-            tmp.append(String8("\r\n"));
-        }
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring juri = env->NewStringUTF(uri);
-    jstring jheaders = env->NewStringUTF(tmp.string());
-
-    jboolean ret =
-        env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);
-
-    env->DeleteLocalRef(juri);
-    env->DeleteLocalRef(jheaders);
-
-    return (bool)ret;
-}
-
-void JMedia2HTTPConnection::disconnect() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
-}
-
-ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-
-    if (size > kBufferSize) {
-        size = kBufferSize;
-    }
-
-    jint n = env->CallIntMethod(
-            mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);
-
-    if (n > 0) {
-        env->GetByteArrayRegion(
-                mByteArrayObj,
-                0,
-                n,
-                (jbyte *)data);
-    }
-
-    return n;
-}
-
-off64_t JMedia2HTTPConnection::getSize() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
-}
-
-status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
-    jboolean flag = env->ExceptionCheck();
-    if (flag) {
-        env->ExceptionClear();
-        return UNKNOWN_ERROR;
-    }
-
-    const char *str = env->GetStringUTFChars(jmime, 0);
-    if (str != NULL) {
-        *mimeType = String8(str);
-    } else {
-        *mimeType = "application/octet-stream";
-    }
-    env->ReleaseStringUTFChars(jmime, str);
-    return OK;
-}
-
-status_t JMedia2HTTPConnection::getUri(String8 *uri) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
-    jboolean flag = env->ExceptionCheck();
-    if (flag) {
-        env->ExceptionClear();
-        return UNKNOWN_ERROR;
-    }
-
-    const char *str = env->GetStringUTFChars(juri, 0);
-    *uri = String8(str);
-    env->ReleaseStringUTFChars(juri, str);
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/jni/android_media_Media2HTTPConnection.h b/media/jni/android_media_Media2HTTPConnection.h
deleted file mode 100644
index 14bc677..0000000
--- a/media/jni/android_media_Media2HTTPConnection.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_MEDIA_MEDIA2HTTPCONNECTION_H_
-#define _ANDROID_MEDIA_MEDIA2HTTPCONNECTION_H_
-
-#include "jni.h"
-
-#include <media/MediaHTTPConnection.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct JMedia2HTTPConnection : public MediaHTTPConnection {
-    JMedia2HTTPConnection(JNIEnv *env, jobject thiz);
-
-    virtual bool connect(
-            const char *uri, const KeyedVector<String8, String8> *headers) override;
-
-    virtual void disconnect() override;
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size) override;
-    virtual off64_t getSize() override;
-    virtual status_t getMIMEType(String8 *mimeType) override;
-    virtual status_t getUri(String8 *uri) override;
-
-protected:
-    virtual ~JMedia2HTTPConnection();
-
-private:
-    jobject mMedia2HTTPConnectionObj;
-    jmethodID mConnectMethod;
-    jmethodID mDisconnectMethod;
-    jmethodID mReadAtMethod;
-    jmethodID mGetSizeMethod;
-    jmethodID mGetMIMETypeMethod;
-    jmethodID mGetUriMethod;
-
-    jbyteArray mByteArrayObj;
-
-    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPConnection);
-};
-
-}  // namespace android
-
-#endif  // _ANDROID_MEDIA_MEDIA2HTTPCONNECTION_H_
diff --git a/media/jni/android_media_Media2HTTPService.cpp b/media/jni/android_media_Media2HTTPService.cpp
deleted file mode 100644
index 1c63889..0000000
--- a/media/jni/android_media_Media2HTTPService.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Media2HTTPService-JNI"
-#include <utils/Log.h>
-
-#include "android_media_Media2HTTPConnection.h"
-#include "android_media_Media2HTTPService.h"
-
-#include "log/log.h"
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-
-#include <mediaplayer2/JavaVMHelper.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <nativehelper/ScopedLocalRef.h>
-
-namespace android {
-
-JMedia2HTTPService::JMedia2HTTPService(JNIEnv *env, jobject thiz) {
-    mMedia2HTTPServiceObj = env->NewGlobalRef(thiz);
-    CHECK(mMedia2HTTPServiceObj != NULL);
-
-    ScopedLocalRef<jclass> media2HTTPServiceClass(env, env->GetObjectClass(mMedia2HTTPServiceObj));
-    CHECK(media2HTTPServiceClass.get() != NULL);
-
-    mMakeHTTPConnectionMethod = env->GetMethodID(
-            media2HTTPServiceClass.get(),
-            "makeHTTPConnection",
-            "()Landroid/media/Media2HTTPConnection;");
-    CHECK(mMakeHTTPConnectionMethod != NULL);
-}
-
-JMedia2HTTPService::~JMedia2HTTPService() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mMedia2HTTPServiceObj);
-}
-
-sp<MediaHTTPConnection> JMedia2HTTPService::makeHTTPConnection() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jobject media2HTTPConnectionObj =
-        env->CallObjectMethod(mMedia2HTTPServiceObj, mMakeHTTPConnectionMethod);
-
-    return new JMedia2HTTPConnection(env, media2HTTPConnectionObj);
-}
-
-}  // namespace android
diff --git a/media/jni/android_media_Media2HTTPService.h b/media/jni/android_media_Media2HTTPService.h
deleted file mode 100644
index 30d03f5..0000000
--- a/media/jni/android_media_Media2HTTPService.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_MEDIA_MEDIA2HTTPSERVICE_H_
-#define _ANDROID_MEDIA_MEDIA2HTTPSERVICE_H_
-
-#include "jni.h"
-
-#include <media/MediaHTTPService.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct JMedia2HTTPService : public MediaHTTPService {
-    JMedia2HTTPService(JNIEnv *env, jobject thiz);
-
-    virtual sp<MediaHTTPConnection> makeHTTPConnection() override;
-
-protected:
-    virtual ~JMedia2HTTPService();
-
-private:
-    jobject mMedia2HTTPServiceObj;
-
-    jmethodID mMakeHTTPConnectionMethod;
-
-    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPService);
-};
-
-}  // namespace android
-
-#endif  // _ANDROID_MEDIA_MEDIA2HTTPSERVICE_H_
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index d4c84b5..693a3d0 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -30,6 +30,7 @@
 #include <media/stagefright/foundation/ByteUtils.h>  // for FOURCC definition
 #include <mediaplayer2/JAudioTrack.h>
 #include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPService.h>
 #include <mediaplayer2/mediaplayer2.h>
 #include <stdio.h>
 #include <assert.h>
@@ -45,7 +46,6 @@
 #include "utils/KeyedVector.h"
 #include "utils/String8.h"
 #include "android_media_BufferingParams.h"
-#include "android_media_Media2HTTPService.h"
 #include "android_media_Media2DataSource.h"
 #include "android_media_MediaMetricsJNI.h"
 #include "android_media_PlaybackParams.h"
@@ -1490,8 +1490,8 @@
     {"_release",            "()V",                              (void *)android_media_MediaPlayer2_release},
     {"_reset",              "()V",                              (void *)android_media_MediaPlayer2_reset},
     {"_getAudioStreamType", "()I",                              (void *)android_media_MediaPlayer2_getAudioStreamType},
-    {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer2_setParameter},
-    {"getParameter",        "(I)Landroid/os/Parcel;",           (void *)android_media_MediaPlayer2_getParameter},
+    {"setParameter",        "(ILjava/lang/Object;)Z",          (void *)android_media_MediaPlayer2_setParameter},
+    {"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},
diff --git a/media/lib/remotedisplay/Android.bp b/media/lib/remotedisplay/Android.bp
index 1e9320d..5f4b930 100644
--- a/media/lib/remotedisplay/Android.bp
+++ b/media/lib/remotedisplay/Android.bp
@@ -14,22 +14,8 @@
 // limitations under the License.
 //
 
-droiddoc {
-    name: "com.android.media.remotedisplay.stubs-gen-docs",
-    srcs: [
-        "java/**/*.java",
-    ],
-    args: " -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " +
-          " -stubpackages com.android.media.remotedisplay " +
-          " -nodocs ",
-    custom_template: "droiddoc-templates-sdk",
-    installable: false,
-}
-
-java_library_static {
-    name: "com.android.media.remotedisplay.stubs",
-    srcs: [
-        ":com.android.media.remotedisplay.stubs-gen-docs",
-    ],
-    sdk_version: "current",
+java_sdk_library {
+    name: "com.android.media.remotedisplay",
+    srcs: ["java/**/*.java"],
+    api_packages: ["com.android.media.remotedisplay"],
 }
diff --git a/media/lib/remotedisplay/Android.mk b/media/lib/remotedisplay/Android.mk
deleted file mode 100644
index e88c0f1..0000000
--- a/media/lib/remotedisplay/Android.mk
+++ /dev/null
@@ -1,44 +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)
-
-# the remotedisplay library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= com.android.media.remotedisplay
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-# ====  com.android.media.remotedisplay.xml lib def  ========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.android.media.remotedisplay.xml
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
diff --git a/media/lib/remotedisplay/OWNERS b/media/lib/remotedisplay/OWNERS
new file mode 100644
index 0000000..7e7335d
--- /dev/null
+++ b/media/lib/remotedisplay/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/media/lib/remotedisplay/api/current.txt b/media/lib/remotedisplay/api/current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/current.txt
diff --git a/media/lib/remotedisplay/api/removed.txt b/media/lib/remotedisplay/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/removed.txt
diff --git a/media/lib/remotedisplay/api/system-current.txt b/media/lib/remotedisplay/api/system-current.txt
new file mode 100644
index 0000000..69bbd35
--- /dev/null
+++ b/media/lib/remotedisplay/api/system-current.txt
@@ -0,0 +1,52 @@
+package com.android.media.remotedisplay {
+
+  public class RemoteDisplay {
+    ctor public RemoteDisplay(java.lang.String, java.lang.String);
+    method public java.lang.String getDescription();
+    method public java.lang.String getId();
+    method public java.lang.String getName();
+    method public int getPresentationDisplayId();
+    method public int getStatus();
+    method public int getVolume();
+    method public int getVolumeHandling();
+    method public int getVolumeMax();
+    method public void setDescription(java.lang.String);
+    method public void setName(java.lang.String);
+    method public void setPresentationDisplayId(int);
+    method public void setStatus(int);
+    method public void setVolume(int);
+    method public void setVolumeHandling(int);
+    method public void setVolumeMax(int);
+    field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+    field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+    field public static final int STATUS_AVAILABLE = 2; // 0x2
+    field public static final int STATUS_CONNECTED = 4; // 0x4
+    field public static final int STATUS_CONNECTING = 3; // 0x3
+    field public static final int STATUS_IN_USE = 1; // 0x1
+    field public static final int STATUS_NOT_AVAILABLE = 0; // 0x0
+  }
+
+  public abstract class RemoteDisplayProvider {
+    ctor public RemoteDisplayProvider(android.content.Context);
+    method public void addDisplay(com.android.media.remotedisplay.RemoteDisplay);
+    method public com.android.media.remotedisplay.RemoteDisplay findRemoteDisplay(java.lang.String);
+    method public android.os.IBinder getBinder();
+    method public final android.content.Context getContext();
+    method public int getDiscoveryMode();
+    method public java.util.Collection<com.android.media.remotedisplay.RemoteDisplay> getDisplays();
+    method public android.app.PendingIntent getSettingsPendingIntent();
+    method public void onAdjustVolume(com.android.media.remotedisplay.RemoteDisplay, int);
+    method public void onConnect(com.android.media.remotedisplay.RemoteDisplay);
+    method public void onDisconnect(com.android.media.remotedisplay.RemoteDisplay);
+    method public void onDiscoveryModeChanged(int);
+    method public void onSetVolume(com.android.media.remotedisplay.RemoteDisplay, int);
+    method public void removeDisplay(com.android.media.remotedisplay.RemoteDisplay);
+    method public void updateDisplay(com.android.media.remotedisplay.RemoteDisplay);
+    field public static final int DISCOVERY_MODE_ACTIVE = 2; // 0x2
+    field public static final int DISCOVERY_MODE_NONE = 0; // 0x0
+    field public static final int DISCOVERY_MODE_PASSIVE = 1; // 0x1
+    field public static final java.lang.String SERVICE_INTERFACE = "com.android.media.remotedisplay.RemoteDisplayProvider";
+  }
+
+}
+
diff --git a/media/lib/remotedisplay/api/system-removed.txt b/media/lib/remotedisplay/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/system-removed.txt
diff --git a/media/lib/remotedisplay/api/test-current.txt b/media/lib/remotedisplay/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/test-current.txt
diff --git a/media/lib/remotedisplay/api/test-removed.txt b/media/lib/remotedisplay/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/test-removed.txt
diff --git a/media/lib/remotedisplay/com.android.media.remotedisplay.xml b/media/lib/remotedisplay/com.android.media.remotedisplay.xml
deleted file mode 100644
index 77a91d2..0000000
--- a/media/lib/remotedisplay/com.android.media.remotedisplay.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<permissions>
-    <library name="com.android.media.remotedisplay"
-            file="/system/framework/com.android.media.remotedisplay.jar" />
-</permissions>
diff --git a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
index dc9dd79..8de414b 100644
--- a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
+++ b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
@@ -16,6 +16,7 @@
 
 package com.android.media.remotedisplay;
 
+import android.annotation.SystemApi;
 import android.media.RemoteDisplayState.RemoteDisplayInfo;
 import android.text.TextUtils;
 
@@ -23,7 +24,10 @@
 
 /**
  * Represents a remote display that has been discovered.
+ *
+ * @hide
  */
+@SystemApi
 public class RemoteDisplay {
     private final RemoteDisplayInfo mMutableInfo;
     private RemoteDisplayInfo mImmutableInfo;
diff --git a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
index 4d3edb8..7017e44 100644
--- a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
+++ b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.media.remotedisplay;
 
+import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
@@ -88,7 +89,10 @@
  * IMPORTANT: This class is effectively a public API for unbundled applications, and
  * must remain API stable. See README.txt in the root of this package for more information.
  * </p>
+ *
+ * @hide
  */
+@SystemApi
 public abstract class RemoteDisplayProvider {
     private static final int MSG_SET_CALLBACK = 1;
     private static final int MSG_SET_DISCOVERY_MODE = 2;
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 3b25787..8c43683 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -18,4 +18,5 @@
     name: "com.android.mediadrm.signer",
     srcs: ["java/**/*.java"],
     api_packages: ["com.android.mediadrm.signer"],
+    metalava_enabled: false,
 }
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/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index b95adad..761a475 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -43,6 +43,9 @@
 struct ASystemFontIterator {
     XmlDocUniquePtr mXmlDoc;
     xmlNode* mFontNode;
+
+    // The OEM customization XML.
+    XmlDocUniquePtr mCustomizationXmlDoc;
 };
 
 struct ASystemFont {
@@ -93,29 +96,30 @@
     return nullptr;
 }
 
-void copyFont(ASystemFontIterator* ite, ASystemFont* out) {
+void copyFont(const XmlDocUniquePtr& xmlDoc, xmlNode* fontNode, ASystemFont* out,
+              const std::string& pathPrefix) {
     const xmlChar* LOCALE_ATTR_NAME = BAD_CAST("lang");
     XmlCharUniquePtr filePathStr(
-            xmlNodeListGetString(ite->mXmlDoc.get(), ite->mFontNode->xmlChildrenNode, 1));
-    out->mFilePath = "/system/fonts/" + xmlTrim(
+            xmlNodeListGetString(xmlDoc.get(), fontNode->xmlChildrenNode, 1));
+    out->mFilePath = pathPrefix + xmlTrim(
             std::string(filePathStr.get(), filePathStr.get() + xmlStrlen(filePathStr.get())));
 
     const xmlChar* WEIGHT_ATTR_NAME = BAD_CAST("weight");
-    XmlCharUniquePtr weightStr(xmlGetProp(ite->mFontNode, WEIGHT_ATTR_NAME));
+    XmlCharUniquePtr weightStr(xmlGetProp(fontNode, WEIGHT_ATTR_NAME));
     out->mWeight = weightStr ?
             strtol(reinterpret_cast<const char*>(weightStr.get()), nullptr, 10) : 400;
 
     const xmlChar* STYLE_ATTR_NAME = BAD_CAST("style");
     const xmlChar* ITALIC_ATTR_VALUE = BAD_CAST("italic");
-    XmlCharUniquePtr styleStr(xmlGetProp(ite->mFontNode, STYLE_ATTR_NAME));
+    XmlCharUniquePtr styleStr(xmlGetProp(fontNode, STYLE_ATTR_NAME));
     out->mItalic = styleStr ? xmlStrEqual(styleStr.get(), ITALIC_ATTR_VALUE) : false;
 
     const xmlChar* INDEX_ATTR_NAME = BAD_CAST("index");
-    XmlCharUniquePtr indexStr(xmlGetProp(ite->mFontNode, INDEX_ATTR_NAME));
+    XmlCharUniquePtr indexStr(xmlGetProp(fontNode, INDEX_ATTR_NAME));
     out->mCollectionIndex =  indexStr ?
             strtol(reinterpret_cast<const char*>(indexStr.get()), nullptr, 10) : 0;
 
-    XmlCharUniquePtr localeStr(xmlGetProp(ite->mXmlDoc->parent, LOCALE_ATTR_NAME));
+    XmlCharUniquePtr localeStr(xmlGetProp(xmlDoc->parent, LOCALE_ATTR_NAME));
     out->mLocale.reset(
             localeStr ? new std::string(reinterpret_cast<const char*>(localeStr.get())) : nullptr);
 
@@ -123,7 +127,7 @@
     const xmlChar* STYLEVALUE_ATTR_NAME = BAD_CAST("stylevalue");
     const xmlChar* AXIS_TAG = BAD_CAST("axis");
     out->mAxes.clear();
-    for (xmlNode* axis = firstElement(ite->mFontNode, AXIS_TAG); axis;
+    for (xmlNode* axis = firstElement(fontNode, AXIS_TAG); axis;
             axis = nextSibling(axis, AXIS_TAG)) {
         XmlCharUniquePtr tagStr(xmlGetProp(axis, TAG_ATTR_NAME));
         if (!tagStr || xmlStrlen(tagStr.get()) != 4) {
@@ -154,8 +158,8 @@
     return S_ISREG(st.st_mode);
 }
 
-xmlNode* findFirstFontNode(xmlDoc* doc) {
-    xmlNode* familySet = xmlDocGetRootElement(doc);
+xmlNode* findFirstFontNode(const XmlDocUniquePtr& doc) {
+    xmlNode* familySet = xmlDocGetRootElement(doc.get());
     if (familySet == nullptr) {
         return nullptr;
     }
@@ -180,6 +184,7 @@
 ASystemFontIterator* ASystemFontIterator_open() {
     std::unique_ptr<ASystemFontIterator> ite(new ASystemFontIterator());
     ite->mXmlDoc.reset(xmlReadFile("/system/etc/fonts.xml", nullptr, 0));
+    ite->mCustomizationXmlDoc.reset(xmlReadFile("/product/etc/fonts_customization.xml", nullptr, 0));
     return ite.release();
 }
 
@@ -187,47 +192,64 @@
     delete ite;
 }
 
-ASystemFont* ASystemFontIterator_next(ASystemFontIterator* ite) {
-    LOG_ALWAYS_FATAL_IF(ite == nullptr, "nullptr has passed as iterator argument");
-    if (ite->mFontNode == nullptr) {
-        if (ite->mXmlDoc == nullptr) {
+xmlNode* findNextFontNode(const XmlDocUniquePtr& xmlDoc, xmlNode* fontNode) {
+    if (fontNode == nullptr) {
+        if (!xmlDoc) {
             return nullptr;  // Already at the end.
         } else {
             // First time to query font.
-            ite->mFontNode = findFirstFontNode(ite->mXmlDoc.get());
-            if (ite->mFontNode == nullptr) {
-                ite->mXmlDoc.reset();
-                return nullptr;  // No font node found.
-            }
-            std::unique_ptr<ASystemFont> font = std::make_unique<ASystemFont>();
-            copyFont(ite, font.get());
-            return font.release();
+            return findFirstFontNode(xmlDoc);
         }
     } else {
-        xmlNode* nextNode = nextSibling(ite->mFontNode, FONT_TAG);
+        xmlNode* nextNode = nextSibling(fontNode, FONT_TAG);
         while (nextNode == nullptr) {
-            xmlNode* family = nextSibling(ite->mFontNode->parent, FAMILY_TAG);
+            xmlNode* family = nextSibling(fontNode->parent, FAMILY_TAG);
             if (family == nullptr) {
                 break;
             }
             nextNode = firstElement(family, FONT_TAG);
         }
-        ite->mFontNode = nextNode;
-        if (nextNode == nullptr) {
-            ite->mXmlDoc.reset();
-            return nullptr;
-        }
-
-        std::unique_ptr<ASystemFont> font = std::make_unique<ASystemFont>();
-        copyFont(ite, font.get());
-        if (!isFontFileAvailable(font->mFilePath)) {
-            // fonts.xml intentionally contains missing font configuration. Skip it.
-            return ASystemFontIterator_next(ite);
-        }
-        return font.release();
+        return nextNode;
     }
 }
 
+ASystemFont* ASystemFontIterator_next(ASystemFontIterator* ite) {
+    LOG_ALWAYS_FATAL_IF(ite == nullptr, "nullptr has passed as iterator argument");
+    if (ite->mXmlDoc) {
+        ite->mFontNode = findNextFontNode(ite->mXmlDoc, ite->mFontNode);
+        if (ite->mFontNode == nullptr) {
+            // Reached end of the XML file. Continue OEM customization.
+            ite->mXmlDoc.reset();
+            ite->mFontNode = nullptr;
+        } else {
+            std::unique_ptr<ASystemFont> font = std::make_unique<ASystemFont>();
+            copyFont(ite->mXmlDoc, ite->mFontNode, font.get(), "/system/fonts/");
+            if (!isFontFileAvailable(font->mFilePath)) {
+                return ASystemFontIterator_next(ite);
+            }
+            return font.release();
+        }
+    }
+    if (ite->mCustomizationXmlDoc) {
+        // TODO: Filter only customizationType="new-named-family"
+        ite->mFontNode = findNextFontNode(ite->mCustomizationXmlDoc, ite->mFontNode);
+        if (ite->mFontNode == nullptr) {
+            // Reached end of the XML file. Finishing
+            ite->mCustomizationXmlDoc.reset();
+            ite->mFontNode = nullptr;
+            return nullptr;
+        } else {
+            std::unique_ptr<ASystemFont> font = std::make_unique<ASystemFont>();
+            copyFont(ite->mCustomizationXmlDoc, ite->mFontNode, font.get(), "/product/fonts/");
+            if (!isFontFileAvailable(font->mFilePath)) {
+                return ASystemFontIterator_next(ite);
+            }
+            return font.release();
+        }
+    }
+    return nullptr;
+}
+
 void ASystemFont_close(ASystemFont* font) {
     delete font;
 }
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
index e64fb76..d8f7be9 100644
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-de/strings.xml
@@ -7,6 +7,6 @@
     <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
     <string name="action_bar_title" msgid="5645564790486983117">"In %1$s anmelden"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört möglicherweise nicht zur angezeigten Organisation."</string>
+    <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Trotzdem in einem Browser fortfahren"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 149de13..0ba37ae 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -130,6 +130,22 @@
             mProbeSpec = null;
         }
 
+        mNetworkCallback = new NetworkCallback() {
+            @Override
+            public void onLost(Network lostNetwork) {
+                // If the network disappears while the app is up, exit.
+                if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED);
+            }
+        };
+        mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkCallback);
+
+        // If the network has disappeared, exit.
+        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
+        if (networkCapabilities == null) {
+            finishAndRemoveTask();
+            return;
+        }
+
         // Also initializes proxy system properties.
         mNetwork = mNetwork.getPrivateDnsBypassingCopy();
         mCm.bindProcessToNetwork(mNetwork);
@@ -139,24 +155,6 @@
         // setContentView initializes the WebView logic which in turn reads the system properties.
         setContentView(R.layout.activity_captive_portal_login);
 
-        // Exit app if Network disappears.
-        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
-        if (networkCapabilities == null) {
-            finishAndRemoveTask();
-            return;
-        }
-        mNetworkCallback = new NetworkCallback() {
-            @Override
-            public void onLost(Network lostNetwork) {
-                if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED);
-            }
-        };
-        final NetworkRequest.Builder builder = new NetworkRequest.Builder();
-        for (int transportType : networkCapabilities.getTransportTypes()) {
-            builder.addTransportType(transportType);
-        }
-        mCm.registerNetworkCallback(builder.build(), mNetworkCallback);
-
         getActionBar().setDisplayShowHomeEnabled(false);
         getActionBar().setElevation(0); // remove shadow
         getActionBar().setTitle(getHeaderTitle());
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
index 86f9032..1b1bf8d 100644
--- a/packages/CarSystemUI/Android.bp
+++ b/packages/CarSystemUI/Android.bp
@@ -30,6 +30,7 @@
         "SystemUIPluginLib",
         "SystemUISharedLib",
         "SettingsLib",
+        "android.car.user",
         "androidx.car_car",
         "androidx.legacy_legacy-support-v4",
         "androidx.recyclerview_recyclerview",
@@ -51,7 +52,6 @@
     libs: [
         "telephony-common",
         "android.car",
-        "android.car.user",
     ],
 
     manifest: "AndroidManifest.xml",
diff --git a/packages/CarrierDefaultApp/res/values-de/strings.xml b/packages/CarrierDefaultApp/res/values-de/strings.xml
index 927b8f0..95639ad 100644
--- a/packages/CarrierDefaultApp/res/values-de/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-de/strings.xml
@@ -12,6 +12,6 @@
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status der mobilen Datennutzung"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"Bei Mobilfunknetz anmelden"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
-    <string name="ssl_error_example" msgid="6188711843183058764">"Beispiel: Die Log-in-Seite gehört möglicherweise nicht zur angezeigten Organisation."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"Trotzdem in einem Browser fortfahren"</string>
 </resources>
diff --git a/packages/LocalTransport/Android.mk b/packages/LocalTransport/Android.mk
new file mode 100644
index 0000000..3484b0f
--- /dev/null
+++ b/packages/LocalTransport/Android.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+LOCAL_PACKAGE_NAME := LocalTransport
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/packages/LocalTransport/AndroidManifest.xml b/packages/LocalTransport/AndroidManifest.xml
new file mode 100644
index 0000000..196be1e
--- /dev/null
+++ b/packages/LocalTransport/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2018 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.localtransport"
+      android:sharedUserId="android.uid.system" >
+
+
+    <application android:allowBackup="false" >
+        <!-- This service does not need to be exported because it shares uid with the system server
+        which is the only client. -->
+        <service android:name=".LocalTransportService"
+                 android:permission="android.permission.CONFIRM_FULL_BACKUP"
+                 android:exported="false">
+            <intent-filter>
+                <action android:name="android.backup.TRANSPORT_HOST" />
+            </intent-filter>
+        </service>
+
+    </application>
+</manifest>
diff --git a/packages/LocalTransport/proguard.flags b/packages/LocalTransport/proguard.flags
new file mode 100644
index 0000000..c1f51b8
--- /dev/null
+++ b/packages/LocalTransport/proguard.flags
@@ -0,0 +1,5 @@
+-keep class com.android.localTransport.LocalTransport
+-keep class com.android.localTransport.LocalTransportParameters
+-keep class com.android.localTransport.LocalTransportService
+
+
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
new file mode 100644
index 0000000..4408ef5
--- /dev/null
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
@@ -0,0 +1,864 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.localtransport;
+
+import android.app.backup.BackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupTransport;
+import android.app.backup.RestoreDescription;
+import android.app.backup.RestoreSet;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
+import android.util.ArrayMap;
+import android.util.Base64;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Backup transport for stashing stuff into a known location on disk, and
+ * later restoring from there.  For testing only.
+ */
+
+public class LocalTransport extends BackupTransport {
+    private static final String TAG = "LocalTransport";
+    private static final boolean DEBUG = false;
+
+    private static final String TRANSPORT_DIR_NAME
+            = "com.android.localtransport.LocalTransport";
+
+    private static final String TRANSPORT_DESTINATION_STRING
+            = "Backing up to debug-only private cache";
+
+    private static final String TRANSPORT_DATA_MANAGEMENT_LABEL
+            = "";
+
+    private static final String INCREMENTAL_DIR = "_delta";
+    private static final String FULL_DATA_DIR = "_full";
+
+    // The currently-active restore set always has the same (nonzero!) token
+    private static final long CURRENT_SET_TOKEN = 1;
+
+    // Size quotas at reasonable values, similar to the current cloud-storage limits
+    private static final long FULL_BACKUP_SIZE_QUOTA = 25 * 1024 * 1024;
+    private static final long KEY_VALUE_BACKUP_SIZE_QUOTA = 5 * 1024 * 1024;
+
+    private Context mContext;
+    private File mDataDir;
+    private File mCurrentSetDir;
+    private File mCurrentSetIncrementalDir;
+    private File mCurrentSetFullDir;
+
+    private PackageInfo[] mRestorePackages = null;
+    private int mRestorePackage = -1;  // Index into mRestorePackages
+    private int mRestoreType;
+    private File mRestoreSetDir;
+    private File mRestoreSetIncrementalDir;
+    private File mRestoreSetFullDir;
+
+    // Additional bookkeeping for full backup
+    private String mFullTargetPackage;
+    private ParcelFileDescriptor mSocket;
+    private FileInputStream mSocketInputStream;
+    private BufferedOutputStream mFullBackupOutputStream;
+    private byte[] mFullBackupBuffer;
+    private long mFullBackupSize;
+
+    private FileInputStream mCurFullRestoreStream;
+    private byte[] mFullRestoreBuffer;
+    private final LocalTransportParameters mParameters;
+
+    private void makeDataDirs() {
+        mDataDir = mContext.getFilesDir();
+        mCurrentSetDir = new File(mDataDir, Long.toString(CURRENT_SET_TOKEN));
+        mCurrentSetIncrementalDir = new File(mCurrentSetDir, INCREMENTAL_DIR);
+        mCurrentSetFullDir = new File(mCurrentSetDir, FULL_DATA_DIR);
+
+        mCurrentSetDir.mkdirs();
+        mCurrentSetFullDir.mkdir();
+        mCurrentSetIncrementalDir.mkdir();
+    }
+
+    public LocalTransport(Context context, LocalTransportParameters parameters) {
+        mContext = context;
+        mParameters = parameters;
+        makeDataDirs();
+    }
+
+    LocalTransportParameters getParameters() {
+        return mParameters;
+    }
+
+    @Override
+    public String name() {
+        return new ComponentName(mContext, this.getClass()).flattenToShortString();
+    }
+
+    @Override
+    public Intent configurationIntent() {
+        // The local transport is not user-configurable
+        return null;
+    }
+
+    @Override
+    public String currentDestinationString() {
+        return TRANSPORT_DESTINATION_STRING;
+    }
+
+    public Intent dataManagementIntent() {
+        // The local transport does not present a data-management UI
+        // TODO: consider adding simple UI to wipe the archives entirely,
+        // for cleaning up the cache partition.
+        return null;
+    }
+
+    public String dataManagementLabel() {
+        return TRANSPORT_DATA_MANAGEMENT_LABEL;
+    }
+
+    @Override
+    public String transportDirName() {
+        return TRANSPORT_DIR_NAME;
+    }
+
+    @Override
+    public int getTransportFlags() {
+        int flags = super.getTransportFlags();
+        // Testing for a fake flag and having it set as a boolean in settings prevents anyone from
+        // using this it to pull data from the agent
+        if (mParameters.isFakeEncryptionFlag()) {
+            flags |= BackupAgent.FLAG_FAKE_CLIENT_SIDE_ENCRYPTION_ENABLED;
+        }
+        return flags;
+    }
+
+    @Override
+    public long requestBackupTime() {
+        // any time is a good time for local backup
+        return 0;
+    }
+
+    @Override
+    public int initializeDevice() {
+        if (DEBUG) Log.v(TAG, "wiping all data");
+        deleteContents(mCurrentSetDir);
+        makeDataDirs();
+        return TRANSPORT_OK;
+    }
+
+    // Encapsulation of a single k/v element change
+    private class KVOperation {
+        final String key;     // Element filename, not the raw key, for efficiency
+        final byte[] value;   // null when this is a deletion operation
+
+        KVOperation(String k, byte[] v) {
+            key = k;
+            value = v;
+        }
+    }
+
+    @Override
+    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
+        return performBackup(packageInfo, data, /*flags=*/ 0);
+    }
+
+    @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;
+
+        if (isIncremental) {
+            Log.i(TAG, "Performing incremental backup for " + packageInfo.packageName);
+        } else if (isNonIncremental) {
+            Log.i(TAG, "Performing non-incremental backup for " + packageInfo.packageName);
+        } else {
+            Log.i(TAG, "Performing backup for " + packageInfo.packageName);
+        }
+
+        if (DEBUG) {
+            try {
+                StructStat ss = Os.fstat(data.getFileDescriptor());
+                Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName
+                        + " size=" + ss.st_size + " flags=" + flags);
+            } catch (ErrnoException e) {
+                Log.w(TAG, "Unable to stat input file in performBackup() on "
+                        + packageInfo.packageName);
+            }
+        }
+
+        File packageDir = new File(mCurrentSetIncrementalDir, packageInfo.packageName);
+        boolean hasDataForPackage = !packageDir.mkdirs();
+
+        if (isIncremental) {
+            if (mParameters.isNonIncrementalOnly() || !hasDataForPackage) {
+                if (mParameters.isNonIncrementalOnly()) {
+                    Log.w(TAG, "Transport is in non-incremental only mode.");
+
+                } else {
+                    Log.w(TAG,
+                            "Requested incremental, but transport currently stores no data for the "
+                                    + "package, requesting non-incremental retry.");
+                }
+                return TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED;
+            }
+        }
+        if (isNonIncremental && hasDataForPackage) {
+            Log.w(TAG, "Requested non-incremental, deleting existing data.");
+            clearBackupData(packageInfo);
+            packageDir.mkdirs();
+        }
+
+        // Each 'record' in the restore set is kept in its own file, named by
+        // the record key.  Wind through the data file, extracting individual
+        // record operations and building a list of all the updates to apply
+        // in this update.
+        final ArrayList<KVOperation> changeOps;
+        try {
+            changeOps = parseBackupStream(data);
+        } catch (IOException e) {
+            // oops, something went wrong.  abort the operation and return error.
+            Log.v(TAG, "Exception reading backup input", e);
+            return TRANSPORT_ERROR;
+        }
+
+        // Okay, now we've parsed out the delta's individual operations.  We need to measure
+        // the effect against what we already have in the datastore to detect quota overrun.
+        // So, we first need to tally up the current in-datastore size per key.
+        final ArrayMap<String, Integer> datastore = new ArrayMap<>();
+        int totalSize = parseKeySizes(packageDir, datastore);
+
+        // ... and now figure out the datastore size that will result from applying the
+        // sequence of delta operations
+        if (DEBUG) {
+            if (changeOps.size() > 0) {
+                Log.v(TAG, "Calculating delta size impact");
+            } else {
+                Log.v(TAG, "No operations in backup stream, so no size change");
+            }
+        }
+        int updatedSize = totalSize;
+        for (KVOperation op : changeOps) {
+            // Deduct the size of the key we're about to replace, if any
+            final Integer curSize = datastore.get(op.key);
+            if (curSize != null) {
+                updatedSize -= curSize.intValue();
+                if (DEBUG && op.value == null) {
+                    Log.v(TAG, "  delete " + op.key + ", updated total " + updatedSize);
+                }
+            }
+
+            // And add back the size of the value we're about to store, if any
+            if (op.value != null) {
+                updatedSize += op.value.length;
+                if (DEBUG) {
+                    Log.v(TAG, ((curSize == null) ? "  new " : "  replace ")
+                            +  op.key + ", updated total " + updatedSize);
+                }
+            }
+        }
+
+        // If our final size is over quota, report the failure
+        if (updatedSize > KEY_VALUE_BACKUP_SIZE_QUOTA) {
+            if (DEBUG) {
+                Log.i(TAG, "New datastore size " + updatedSize
+                        + " exceeds quota " + KEY_VALUE_BACKUP_SIZE_QUOTA);
+            }
+            return TRANSPORT_QUOTA_EXCEEDED;
+        }
+
+        // No problem with storage size, so go ahead and apply the delta operations
+        // (in the order that the app provided them)
+        for (KVOperation op : changeOps) {
+            File element = new File(packageDir, op.key);
+
+            // this is either a deletion or a rewrite-from-zero, so we can just remove
+            // the existing file and proceed in either case.
+            element.delete();
+
+            // if this wasn't a deletion, put the new data in place
+            if (op.value != null) {
+                try (FileOutputStream out = new FileOutputStream(element)) {
+                    out.write(op.value, 0, op.value.length);
+                } catch (IOException e) {
+                    Log.e(TAG, "Unable to update key file " + element);
+                    return TRANSPORT_ERROR;
+                }
+            }
+        }
+        return TRANSPORT_OK;
+    }
+
+    // Parses a backup stream into individual key/value operations
+    private ArrayList<KVOperation> parseBackupStream(ParcelFileDescriptor data)
+            throws IOException {
+        ArrayList<KVOperation> changeOps = new ArrayList<>();
+        BackupDataInput changeSet = new BackupDataInput(data.getFileDescriptor());
+        while (changeSet.readNextHeader()) {
+            String key = changeSet.getKey();
+            String base64Key = new String(Base64.encode(key.getBytes(), Base64.NO_WRAP));
+            int dataSize = changeSet.getDataSize();
+            if (DEBUG) {
+                Log.v(TAG, "  Delta operation key " + key + "   size " + dataSize
+                        + "   key64 " + base64Key);
+            }
+
+            byte[] buf = (dataSize >= 0) ? new byte[dataSize] : null;
+            if (dataSize >= 0) {
+                changeSet.readEntityData(buf, 0, dataSize);
+            }
+            changeOps.add(new KVOperation(base64Key, buf));
+        }
+        return changeOps;
+    }
+
+    // Reads the given datastore directory, building a table of the value size of each
+    // keyed element, and returning the summed total.
+    private int parseKeySizes(File packageDir, ArrayMap<String, Integer> datastore) {
+        int totalSize = 0;
+        final String[] elements = packageDir.list();
+        if (elements != null) {
+            if (DEBUG) {
+                Log.v(TAG, "Existing datastore contents:");
+            }
+            for (String file : elements) {
+                File element = new File(packageDir, file);
+                String key = file;  // filename
+                int size = (int) element.length();
+                totalSize += size;
+                if (DEBUG) {
+                    Log.v(TAG, "  key " + key + "   size " + size);
+                }
+                datastore.put(key, size);
+            }
+            if (DEBUG) {
+                Log.v(TAG, "  TOTAL: " + totalSize);
+            }
+        } else {
+            if (DEBUG) {
+                Log.v(TAG, "No existing data for this package");
+            }
+        }
+        return totalSize;
+    }
+
+    // Deletes the contents but not the given directory
+    private void deleteContents(File dirname) {
+        File[] contents = dirname.listFiles();
+        if (contents != null) {
+            for (File f : contents) {
+                if (f.isDirectory()) {
+                    // delete the directory's contents then fall through
+                    // and delete the directory itself.
+                    deleteContents(f);
+                }
+                f.delete();
+            }
+        }
+    }
+
+    @Override
+    public int clearBackupData(PackageInfo packageInfo) {
+        if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
+
+        File packageDir = new File(mCurrentSetIncrementalDir, packageInfo.packageName);
+        final File[] fileset = packageDir.listFiles();
+        if (fileset != null) {
+            for (File f : fileset) {
+                f.delete();
+            }
+            packageDir.delete();
+        }
+
+        packageDir = new File(mCurrentSetFullDir, packageInfo.packageName);
+        final File[] tarballs = packageDir.listFiles();
+        if (tarballs != null) {
+            for (File f : tarballs) {
+                f.delete();
+            }
+            packageDir.delete();
+        }
+
+        return TRANSPORT_OK;
+    }
+
+    @Override
+    public int finishBackup() {
+        if (DEBUG) Log.v(TAG, "finishBackup() of " + mFullTargetPackage);
+        return tearDownFullBackup();
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Full backup handling
+
+    private int tearDownFullBackup() {
+        if (mSocket != null) {
+            try {
+                if (mFullBackupOutputStream != null) {
+                    mFullBackupOutputStream.flush();
+                    mFullBackupOutputStream.close();
+                }
+                mSocketInputStream = null;
+                mFullTargetPackage = null;
+                mSocket.close();
+            } catch (IOException e) {
+                if (DEBUG) {
+                    Log.w(TAG, "Exception caught in tearDownFullBackup()", e);
+                }
+                return TRANSPORT_ERROR;
+            } finally {
+                mSocket = null;
+                mFullBackupOutputStream = null;
+            }
+        }
+        return TRANSPORT_OK;
+    }
+
+    private File tarballFile(String pkgName) {
+        return new File(mCurrentSetFullDir, pkgName);
+    }
+
+    @Override
+    public long requestFullBackupTime() {
+        return 0;
+    }
+
+    @Override
+    public int checkFullBackupSize(long size) {
+        int result = TRANSPORT_OK;
+        // Decline zero-size "backups"
+        if (size <= 0) {
+            result = TRANSPORT_PACKAGE_REJECTED;
+        } else if (size > FULL_BACKUP_SIZE_QUOTA) {
+            result = TRANSPORT_QUOTA_EXCEEDED;
+        }
+        if (result != TRANSPORT_OK) {
+            if (DEBUG) {
+                Log.v(TAG, "Declining backup of size " + size);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) {
+        if (mSocket != null) {
+            Log.e(TAG, "Attempt to initiate full backup while one is in progress");
+            return TRANSPORT_ERROR;
+        }
+
+        if (DEBUG) {
+            Log.i(TAG, "performFullBackup : " + targetPackage);
+        }
+
+        // We know a priori that we run in the system process, so we need to make
+        // sure to dup() our own copy of the socket fd.  Transports which run in
+        // their own processes must not do this.
+        try {
+            mFullBackupSize = 0;
+            mSocket = ParcelFileDescriptor.dup(socket.getFileDescriptor());
+            mSocketInputStream = new FileInputStream(mSocket.getFileDescriptor());
+        } catch (IOException e) {
+            Log.e(TAG, "Unable to process socket for full backup");
+            return TRANSPORT_ERROR;
+        }
+
+        mFullTargetPackage = targetPackage.packageName;
+        mFullBackupBuffer = new byte[4096];
+
+        return TRANSPORT_OK;
+    }
+
+    @Override
+    public int sendBackupData(final int numBytes) {
+        if (mSocket == null) {
+            Log.w(TAG, "Attempted sendBackupData before performFullBackup");
+            return TRANSPORT_ERROR;
+        }
+
+        mFullBackupSize += numBytes;
+        if (mFullBackupSize > FULL_BACKUP_SIZE_QUOTA) {
+            return TRANSPORT_QUOTA_EXCEEDED;
+        }
+
+        if (numBytes > mFullBackupBuffer.length) {
+            mFullBackupBuffer = new byte[numBytes];
+        }
+
+        if (mFullBackupOutputStream == null) {
+            FileOutputStream tarstream;
+            try {
+                File tarball = tarballFile(mFullTargetPackage);
+                tarstream = new FileOutputStream(tarball);
+            } catch (FileNotFoundException e) {
+                return TRANSPORT_ERROR;
+            }
+            mFullBackupOutputStream = new BufferedOutputStream(tarstream);
+        }
+
+        int bytesLeft = numBytes;
+        while (bytesLeft > 0) {
+            try {
+            int nRead = mSocketInputStream.read(mFullBackupBuffer, 0, bytesLeft);
+            if (nRead < 0) {
+                // Something went wrong if we expect data but saw EOD
+                Log.w(TAG, "Unexpected EOD; failing backup");
+                return TRANSPORT_ERROR;
+            }
+            mFullBackupOutputStream.write(mFullBackupBuffer, 0, nRead);
+            bytesLeft -= nRead;
+            } catch (IOException e) {
+                Log.e(TAG, "Error handling backup data for " + mFullTargetPackage);
+                return TRANSPORT_ERROR;
+            }
+        }
+        if (DEBUG) {
+            Log.v(TAG, "   stored " + numBytes + " of data");
+        }
+        return TRANSPORT_OK;
+    }
+
+    // For now we can't roll back, so just tear everything down.
+    @Override
+    public void cancelFullBackup() {
+        if (DEBUG) {
+            Log.i(TAG, "Canceling full backup of " + mFullTargetPackage);
+        }
+        File archive = tarballFile(mFullTargetPackage);
+        tearDownFullBackup();
+        if (archive.exists()) {
+            archive.delete();
+        }
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Restore handling
+    static final long[] POSSIBLE_SETS = { 2, 3, 4, 5, 6, 7, 8, 9 };
+
+    @Override
+    public RestoreSet[] getAvailableRestoreSets() {
+        long[] existing = new long[POSSIBLE_SETS.length + 1];
+        int num = 0;
+
+        // see which possible non-current sets exist...
+        for (long token : POSSIBLE_SETS) {
+            if ((new File(mDataDir, Long.toString(token))).exists()) {
+                existing[num++] = token;
+            }
+        }
+        // ...and always the currently-active set last
+        existing[num++] = CURRENT_SET_TOKEN;
+
+        RestoreSet[] available = new RestoreSet[num];
+        for (int i = 0; i < available.length; i++) {
+            available[i] = new RestoreSet("Local disk image", "flash", existing[i]);
+        }
+        return available;
+    }
+
+    @Override
+    public long getCurrentRestoreSet() {
+        // The current restore set always has the same token
+        return CURRENT_SET_TOKEN;
+    }
+
+    @Override
+    public int startRestore(long token, PackageInfo[] packages) {
+        if (DEBUG) Log.v(TAG, "start restore " + token + " : " + packages.length
+                + " matching packages");
+        mRestorePackages = packages;
+        mRestorePackage = -1;
+        mRestoreSetDir = new File(mDataDir, Long.toString(token));
+        mRestoreSetIncrementalDir = new File(mRestoreSetDir, INCREMENTAL_DIR);
+        mRestoreSetFullDir = new File(mRestoreSetDir, FULL_DATA_DIR);
+        return TRANSPORT_OK;
+    }
+
+    @Override
+    public RestoreDescription nextRestorePackage() {
+        if (DEBUG) {
+            Log.v(TAG, "nextRestorePackage() : mRestorePackage=" + mRestorePackage
+                    + " length=" + mRestorePackages.length);
+        }
+        if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
+
+        boolean found = false;
+        while (++mRestorePackage < mRestorePackages.length) {
+            String name = mRestorePackages[mRestorePackage].packageName;
+
+            // If we have key/value data for this package, deliver that
+            // skip packages where we have a data dir but no actual contents
+            String[] contents = (new File(mRestoreSetIncrementalDir, name)).list();
+            if (contents != null && contents.length > 0) {
+                if (DEBUG) {
+                    Log.v(TAG, "  nextRestorePackage(TYPE_KEY_VALUE) @ "
+                        + mRestorePackage + " = " + name);
+                }
+                mRestoreType = RestoreDescription.TYPE_KEY_VALUE;
+                found = true;
+            }
+
+            if (!found) {
+                // No key/value data; check for [non-empty] full data
+                File maybeFullData = new File(mRestoreSetFullDir, name);
+                if (maybeFullData.length() > 0) {
+                    if (DEBUG) {
+                        Log.v(TAG, "  nextRestorePackage(TYPE_FULL_STREAM) @ "
+                                + mRestorePackage + " = " + name);
+                    }
+                    mRestoreType = RestoreDescription.TYPE_FULL_STREAM;
+                    mCurFullRestoreStream = null;   // ensure starting from the ground state
+                    found = true;
+                }
+            }
+
+            if (found) {
+                return new RestoreDescription(name, mRestoreType);
+            }
+
+            if (DEBUG) {
+                Log.v(TAG, "  ... package @ " + mRestorePackage + " = " + name
+                        + " has no data; skipping");
+            }
+        }
+
+        if (DEBUG) Log.v(TAG, "  no more packages to restore");
+        return RestoreDescription.NO_MORE_PACKAGES;
+    }
+
+    @Override
+    public int getRestoreData(ParcelFileDescriptor outFd) {
+        if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
+        if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called");
+        if (mRestoreType != RestoreDescription.TYPE_KEY_VALUE) {
+            throw new IllegalStateException("getRestoreData(fd) for non-key/value dataset");
+        }
+        File packageDir = new File(mRestoreSetIncrementalDir,
+                mRestorePackages[mRestorePackage].packageName);
+
+        // The restore set is the concatenation of the individual record blobs,
+        // each of which is a file in the package's directory.  We return the
+        // data in lexical order sorted by key, so that apps which use synthetic
+        // keys like BLOB_1, BLOB_2, etc will see the date in the most obvious
+        // order.
+        ArrayList<DecodedFilename> blobs = contentsByKey(packageDir);
+        if (blobs == null) {  // nextRestorePackage() ensures the dir exists, so this is an error
+            Log.e(TAG, "No keys for package: " + packageDir);
+            return TRANSPORT_ERROR;
+        }
+
+        // We expect at least some data if the directory exists in the first place
+        if (DEBUG) Log.v(TAG, "  getRestoreData() found " + blobs.size() + " key files");
+        BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor());
+        try {
+            for (DecodedFilename keyEntry : blobs) {
+                File f = keyEntry.file;
+                FileInputStream in = new FileInputStream(f);
+                try {
+                    int size = (int) f.length();
+                    byte[] buf = new byte[size];
+                    in.read(buf);
+                    if (DEBUG) Log.v(TAG, "    ... key=" + keyEntry.key + " size=" + size);
+                    out.writeEntityHeader(keyEntry.key, size);
+                    out.writeEntityData(buf, size);
+                } finally {
+                    in.close();
+                }
+            }
+            return TRANSPORT_OK;
+        } catch (IOException e) {
+            Log.e(TAG, "Unable to read backup records", e);
+            return TRANSPORT_ERROR;
+        }
+    }
+
+    static class DecodedFilename implements Comparable<DecodedFilename> {
+        public File file;
+        public String key;
+
+        public DecodedFilename(File f) {
+            file = f;
+            key = new String(Base64.decode(f.getName(), Base64.DEFAULT));
+        }
+
+        @Override
+        public int compareTo(DecodedFilename other) {
+            // sorts into ascending lexical order by decoded key
+            return key.compareTo(other.key);
+        }
+    }
+
+    // Return a list of the files in the given directory, sorted lexically by
+    // the Base64-decoded file name, not by the on-disk filename
+    private ArrayList<DecodedFilename> contentsByKey(File dir) {
+        File[] allFiles = dir.listFiles();
+        if (allFiles == null || allFiles.length == 0) {
+            return null;
+        }
+
+        // Decode the filenames into keys then sort lexically by key
+        ArrayList<DecodedFilename> contents = new ArrayList<DecodedFilename>();
+        for (File f : allFiles) {
+            contents.add(new DecodedFilename(f));
+        }
+        Collections.sort(contents);
+        return contents;
+    }
+
+    @Override
+    public void finishRestore() {
+        if (DEBUG) Log.v(TAG, "finishRestore()");
+        if (mRestoreType == RestoreDescription.TYPE_FULL_STREAM) {
+            resetFullRestoreState();
+        }
+        mRestoreType = 0;
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Full restore handling
+
+    private void resetFullRestoreState() {
+        IoUtils.closeQuietly(mCurFullRestoreStream);
+        mCurFullRestoreStream = null;
+        mFullRestoreBuffer = null;
+    }
+
+    /**
+     * Ask the transport to provide data for the "current" package being restored.  The
+     * transport then writes some data to the socket supplied to this call, and returns
+     * the number of bytes written.  The system will then read that many bytes and
+     * stream them to the application's agent for restore, then will call this method again
+     * to receive the next chunk of the archive.  This sequence will be repeated until the
+     * transport returns zero indicating that all of the package's data has been delivered
+     * (or returns a negative value indicating some sort of hard error condition at the
+     * transport level).
+     *
+     * <p>After this method returns zero, the system will then call
+     * {@link #getNextFullRestorePackage()} to begin the restore process for the next
+     * application, and the sequence begins again.
+     *
+     * @param socket The file descriptor that the transport will use for delivering the
+     *    streamed archive.
+     * @return 0 when no more data for the current package is available.  A positive value
+     *    indicates the presence of that much data to be delivered to the app.  A negative
+     *    return value is treated as equivalent to {@link BackupTransport#TRANSPORT_ERROR},
+     *    indicating a fatal error condition that precludes further restore operations
+     *    on the current dataset.
+     */
+    @Override
+    public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
+        if (mRestoreType != RestoreDescription.TYPE_FULL_STREAM) {
+            throw new IllegalStateException("Asked for full restore data for non-stream package");
+        }
+
+        // first chunk?
+        if (mCurFullRestoreStream == null) {
+            final String name = mRestorePackages[mRestorePackage].packageName;
+            if (DEBUG) Log.i(TAG, "Starting full restore of " + name);
+            File dataset = new File(mRestoreSetFullDir, name);
+            try {
+                mCurFullRestoreStream = new FileInputStream(dataset);
+            } catch (IOException e) {
+                // If we can't open the target package's tarball, we return the single-package
+                // error code and let the caller go on to the next package.
+                Log.e(TAG, "Unable to read archive for " + name);
+                return TRANSPORT_PACKAGE_REJECTED;
+            }
+            mFullRestoreBuffer = new byte[2*1024];
+        }
+
+        FileOutputStream stream = new FileOutputStream(socket.getFileDescriptor());
+
+        int nRead;
+        try {
+            nRead = mCurFullRestoreStream.read(mFullRestoreBuffer);
+            if (nRead < 0) {
+                // EOF: tell the caller we're done
+                nRead = NO_MORE_DATA;
+            } else if (nRead == 0) {
+                // This shouldn't happen when reading a FileInputStream; we should always
+                // get either a positive nonzero byte count or -1.  Log the situation and
+                // treat it as EOF.
+                Log.w(TAG, "read() of archive file returned 0; treating as EOF");
+                nRead = NO_MORE_DATA;
+            } else {
+                if (DEBUG) {
+                    Log.i(TAG, "   delivering restore chunk: " + nRead);
+                }
+                stream.write(mFullRestoreBuffer, 0, nRead);
+            }
+        } catch (IOException e) {
+            return TRANSPORT_ERROR;  // Hard error accessing the file; shouldn't happen
+        } finally {
+            IoUtils.closeQuietly(socket);
+        }
+
+        return nRead;
+    }
+
+    /**
+     * If the OS encounters an error while processing {@link RestoreDescription#TYPE_FULL_STREAM}
+     * data for restore, it will invoke this method to tell the transport that it should
+     * abandon the data download for the current package.  The OS will then either call
+     * {@link #nextRestorePackage()} again to move on to restoring the next package in the
+     * set being iterated over, or will call {@link #finishRestore()} to shut down the restore
+     * operation.
+     *
+     * @return {@link #TRANSPORT_OK} if the transport was successful in shutting down the
+     *    current stream cleanly, or {@link #TRANSPORT_ERROR} to indicate a serious
+     *    transport-level failure.  If the transport reports an error here, the entire restore
+     *    operation will immediately be finished with no further attempts to restore app data.
+     */
+    @Override
+    public int abortFullRestore() {
+        if (mRestoreType != RestoreDescription.TYPE_FULL_STREAM) {
+            throw new IllegalStateException("abortFullRestore() but not currently restoring");
+        }
+        resetFullRestoreState();
+        mRestoreType = 0;
+        return TRANSPORT_OK;
+    }
+
+    @Override
+    public long getBackupQuota(String packageName, boolean isFullBackup) {
+        return isFullBackup ? FULL_BACKUP_SIZE_QUOTA : KEY_VALUE_BACKUP_SIZE_QUOTA;
+    }
+}
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java
new file mode 100644
index 0000000..784be22
--- /dev/null
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransportParameters.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.localtransport;
+
+import android.util.KeyValueSettingObserver;
+import android.content.ContentResolver;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.KeyValueListParser;
+
+class LocalTransportParameters extends KeyValueSettingObserver {
+    private static final String TAG = "LocalTransportParams";
+    private static final String SETTING = Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS;
+    private static final String KEY_FAKE_ENCRYPTION_FLAG = "fake_encryption_flag";
+    private static final String KEY_NON_INCREMENTAL_ONLY = "non_incremental_only";
+
+    private boolean mFakeEncryptionFlag;
+    private boolean mIsNonIncrementalOnly;
+
+    LocalTransportParameters(Handler handler, ContentResolver resolver) {
+        super(handler, resolver, Settings.Secure.getUriFor(SETTING));
+    }
+
+    boolean isFakeEncryptionFlag() {
+        return mFakeEncryptionFlag;
+    }
+
+    boolean isNonIncrementalOnly() {
+        return mIsNonIncrementalOnly;
+    }
+
+    public String getSettingValue(ContentResolver resolver) {
+        return Settings.Secure.getString(resolver, SETTING);
+    }
+
+    public void update(KeyValueListParser parser) {
+        mFakeEncryptionFlag = parser.getBoolean(KEY_FAKE_ENCRYPTION_FLAG, false);
+        mIsNonIncrementalOnly = parser.getBoolean(KEY_NON_INCREMENTAL_ONLY, false);
+    }
+}
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java
new file mode 100644
index 0000000..ac4f418
--- /dev/null
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransportService.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+package com.android.localtransport;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class LocalTransportService extends Service {
+    private static LocalTransport sTransport = null;
+
+    @Override
+    public void onCreate() {
+        if (sTransport == null) {
+            LocalTransportParameters parameters =
+                    new LocalTransportParameters(getMainThreadHandler(), getContentResolver());
+            sTransport = new LocalTransport(this, parameters);
+        }
+        sTransport.getParameters().start();
+    }
+
+    @Override
+    public void onDestroy() {
+        sTransport.getParameters().stop();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return sTransport.getBinder();
+    }
+}
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/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index deb6163..9f38d48 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -137,6 +137,7 @@
                         UID_UNKNOWN);
                 params.installerPackageName =
                         getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
+                params.installReason = PackageManager.INSTALL_REASON_USER;
 
                 File file = new File(mPackageURI.getPath());
                 try {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index b3f1105..8fed367 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -106,6 +106,9 @@
 
             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/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 580308a..8c29a25 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -430,9 +430,14 @@
             // Check for unknown sources restriction
             final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource(
                     UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle());
-            if ((unknownSourcesRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
+            final int unknownSourcesGlobalRestrictionSource = mUserManager.getUserRestrictionSource(
+                    UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, Process.myUserHandle());
+            final int systemRestriction = UserManager.RESTRICTION_SOURCE_SYSTEM
+                    & (unknownSourcesRestrictionSource | unknownSourcesGlobalRestrictionSource);
+            if (systemRestriction != 0) {
                 showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER);
-            } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
+            } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET
+                    || unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
                 startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
                 finish();
             } else {
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/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index c02e3c7..e46ff15 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -103,7 +103,7 @@
     <item msgid="3199660090246166812">"Querformat"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"Fehler beim Schreiben in Datei"</string>
-    <string name="print_error_default_message" msgid="8602678405502922346">"Fehler. Bitte versuche es erneut."</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"Fehler. Bitte versuche es noch einmal."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Erneut versuchen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Dieser Drucker ist momentan nicht verfügbar."</string>
     <string name="print_cannot_load_page" msgid="6179560924492912009">"Vorschau kann nicht angezeigt werden"</string>
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/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 943dd84..d60dbe7 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -14,6 +14,9 @@
     static_libs: [
         "SettingsLibHelpUtils",
         "SettingsLibRestrictedLockUtils",
+        "SettingsLibAppPreference",
+        "SettingsLibSearchWidget",
+        "SettingsLibSettingsSpinner",
     ],
 
     // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
diff --git a/packages/SettingsLib/AppPreference/Android.bp b/packages/SettingsLib/AppPreference/Android.bp
new file mode 100644
index 0000000..b56181d
--- /dev/null
+++ b/packages/SettingsLib/AppPreference/Android.bp
@@ -0,0 +1,13 @@
+android_library {
+    name: "SettingsLibAppPreference",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+
+    libs: [
+        "androidx.annotation_annotation",
+        "androidx.preference_preference",
+    ],
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/AppPreference/AndroidManifest.xml b/packages/SettingsLib/AppPreference/AndroidManifest.xml
new file mode 100644
index 0000000..7e71308
--- /dev/null
+++ b/packages/SettingsLib/AppPreference/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.apppreference">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
new file mode 100644
index 0000000..6d35550
--- /dev/null
+++ b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/selectableItemBackground"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="start|center_vertical"
+        android:minWidth="56dp"
+        android:orientation="horizontal"
+        android:paddingEnd="8dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="@dimen/secondary_app_icon_size"
+            android:layout_height="@dimen/secondary_app_icon_size"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingTop="16dp"
+        android:paddingBottom="16dp">
+
+        <TextView android:id="@android:id/title"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                  android:ellipsize="marquee"
+                  android:fadingEdge="horizontal"/>
+
+        <LinearLayout
+            android:id="@+id/summary_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <TextView android:id="@android:id/summary"
+                      android:layout_width="0dp"
+                      android:layout_height="wrap_content"
+                      android:layout_weight="1"
+                      android:textAppearance="@android:style/TextAppearance.Material.Small"
+                      android:textAlignment="viewStart"
+                      android:textColor="?android:attr/textColorSecondary"/>
+
+            <TextView android:id="@+id/appendix"
+                      android:layout_width="0dp"
+                      android:layout_height="wrap_content"
+                      android:layout_weight="1"
+                      android:textAppearance="@android:style/TextAppearance.Material.Small"
+                      android:textAlignment="viewEnd"
+                      android:textColor="?android:attr/textColorSecondary"
+                      android:maxLines="1"
+                      android:ellipsize="end"/>
+        </LinearLayout>
+        <ProgressBar
+            android:id="@android:id/progress"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:max="100"
+            android:visibility="gone"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@android:id/widget_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:minWidth="64dp"
+        android:orientation="vertical"/>
+
+</LinearLayout>
diff --git a/packages/SettingsLib/AppPreference/res/values/dimens.xml b/packages/SettingsLib/AppPreference/res/values/dimens.xml
new file mode 100644
index 0000000..e2a7a19
--- /dev/null
+++ b/packages/SettingsLib/AppPreference/res/values/dimens.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.
+  -->
+
+<resources>
+    <dimen name="secondary_app_icon_size">32dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java
new file mode 100644
index 0000000..593b6f5
--- /dev/null
+++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/apppreference/AppPreference.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.apppreference;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ProgressBar;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+public class AppPreference extends Preference {
+
+    private int mProgress;
+    private boolean mProgressVisible;
+
+    public AppPreference(Context context) {
+        super(context);
+        setLayoutResource(R.layout.preference_app);
+    }
+
+    public AppPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setLayoutResource(R.layout.preference_app);
+    }
+
+    public void setProgress(int amount) {
+        mProgress = amount;
+        mProgressVisible = true;
+        notifyChanged();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder view) {
+        super.onBindViewHolder(view);
+
+        view.findViewById(R.id.summary_container)
+                .setVisibility(TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE);
+        final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
+        if (mProgressVisible) {
+            progress.setProgress(mProgress);
+            progress.setVisibility(View.VISIBLE);
+        } else {
+            progress.setVisibility(View.GONE);
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/HelpUtils/res/values-ml/strings.xml b/packages/SettingsLib/HelpUtils/res/values-ml/strings.xml
index d2a7452..731257e 100644
--- a/packages/SettingsLib/HelpUtils/res/values-ml/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-ml/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="help_feedback_label" msgid="4550436169116444686">"സഹായം &amp; ഫീഡ്‌ബാക്ക്"</string>
+    <string name="help_feedback_label" msgid="4550436169116444686">"സഹായവും ഫീഡ്‌ബാക്കും"</string>
 </resources>
diff --git a/packages/SettingsLib/HelpUtils/res/values-nl/strings.xml b/packages/SettingsLib/HelpUtils/res/values-nl/strings.xml
index a034d29..2f576e6 100644
--- a/packages/SettingsLib/HelpUtils/res/values-nl/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-nl/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="help_feedback_label" msgid="4550436169116444686">"Help en feedback"</string>
+    <string name="help_feedback_label" msgid="4550436169116444686">"Hulp en feedback"</string>
 </resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-af/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-af/strings.xml
new file mode 100644
index 0000000..dced02c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-af/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Geaktiveer deur administrateur"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Gedeaktiveer deur administrateur"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-am/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-am/strings.xml
new file mode 100644
index 0000000..d13be0c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-am/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"በአስተዳዳሪ ነቅቷል"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"በአስተዳዳሪ ተሰናክሏል"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml
new file mode 100644
index 0000000..15c0010
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"فعَّل المشرف هذا الإعداد."</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"أوقف المشرف هذا الإعداد."</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-as/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-as/strings.xml
new file mode 100644
index 0000000..7a3b8e4
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-as/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"প্ৰশাসকে সক্ষম কৰিছে"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"প্ৰশাসকে অক্ষম কৰিছে"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-az/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-az/strings.xml
new file mode 100644
index 0000000..d1434bd
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-az/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Admin tərəfindən aktiv edildi"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Admin tərəfindən deaktiv edildi"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..ee61192
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Administrator je omogućio"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Administrator je onemogućio"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-be/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-be/strings.xml
new file mode 100644
index 0000000..2d13d45
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-be/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Уключана адміністратарам"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Адключана адміністратарам"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-bg/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-bg/strings.xml
new file mode 100644
index 0000000..361910c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-bg/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Активирано от администратора"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Деактивирано от администратора"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-bn/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-bn/strings.xml
new file mode 100644
index 0000000..7609166
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-bn/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"অ্যাডমিন চালু করেছেন"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"অ্যাডমিন বন্ধ করেছেন"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-bs/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-bs/strings.xml
new file mode 100644
index 0000000..9704095
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-bs/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Omogućio administrator"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Onemogućio administrator"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ca/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ca/strings.xml
new file mode 100644
index 0000000..5569664
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ca/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Activat per l\'administrador"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Desactivat per l\'administrador"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-cs/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-cs/strings.xml
new file mode 100644
index 0000000..f8120aa
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-cs/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Zapnuto administrátorem"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Vypnuto administrátorem"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml
new file mode 100644
index 0000000..d75f27b
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Aktiveret af administratoren"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Deaktiveret af administratoren"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-de/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-de/strings.xml
new file mode 100644
index 0000000..3ef46d9
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-de/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Vom Administrator aktiviert"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Vom Administrator deaktiviert"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-el/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-el/strings.xml
new file mode 100644
index 0000000..643686e
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-el/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Ενεργοποιήθηκε από τον διαχειριστή"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Απενεργοποιήθηκε από τον διαχειριστή"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rAU/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..69c0bc3
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Enabled by admin"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Disabled by admin"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rCA/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..69c0bc3
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Enabled by admin"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Disabled by admin"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rGB/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..69c0bc3
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Enabled by admin"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Disabled by admin"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rIN/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..69c0bc3
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Enabled by admin"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Disabled by admin"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..f329a76
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎Enabled by admin‎‏‎‎‏‎"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‎Disabled by admin‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-es-rUS/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..451ea35
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-es-rUS/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"El administrador habilitó la opción"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"El administrador inhabilitó la opción"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml
new file mode 100644
index 0000000..3407d13
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Habilitada por el administrador"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Inhabilitada por el administrador"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-et/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-et/strings.xml
new file mode 100644
index 0000000..98bad62
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-et/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Administraatori lubatud"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Administraatori keelatud"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml
new file mode 100644
index 0000000..1641a31
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Administratzaileak gaitu egin du"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Administratzaileak desgaitu egin du"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-fa/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-fa/strings.xml
new file mode 100644
index 0000000..f4c8334
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-fa/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"فعال‌شده توسط سرپرست"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"غیرفعال‌شده توسط سرپرست"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-fi/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-fi/strings.xml
new file mode 100644
index 0000000..dd62c1a
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-fi/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Järjestelmänvalvojan sallima"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Järjestelmänvalvojan estämä"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..85ec907
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Activé par l\'administrateur"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Désactivé par l\'administrateur"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-fr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-fr/strings.xml
new file mode 100644
index 0000000..85ec907
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-fr/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Activé par l\'administrateur"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Désactivé par l\'administrateur"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-gl/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-gl/strings.xml
new file mode 100644
index 0000000..0d67cc2
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-gl/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Opción activada polo administrador"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Opción desactivada polo administrador"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
new file mode 100644
index 0000000..076c1be
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"વ્યવસ્થાપકે ચાલુ કરેલ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"વ્યવસ્થાપકે બંધ કરેલ"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml
new file mode 100644
index 0000000..75d103f
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"एडमिन की ओर से चालू किया गया"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"एडमिन की ओर से बंद किया गया"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hr/strings.xml
new file mode 100644
index 0000000..9704095
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hr/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Omogućio administrator"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Onemogućio administrator"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml
new file mode 100644
index 0000000..be1cb97
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hu/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"A rendszergazda bekapcsolta"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"A rendszergazda kikapcsolta"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hy/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hy/strings.xml
new file mode 100644
index 0000000..78dab28
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hy/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Միացված է ադմինիստրատորի կողմից"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Անջատվել է ադմինիստրատորի կողմից"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-in/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-in/strings.xml
new file mode 100644
index 0000000..824ddde
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-in/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Diaktifkan oleh admin"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Dinonaktifkan oleh admin"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-is/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-is/strings.xml
new file mode 100644
index 0000000..0707a67
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-is/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Gert virkt af kerfisstjóra"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Gert óvirkt af kerfisstjóra"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml
new file mode 100644
index 0000000..084a47b
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Attivata dall\'amministratore"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Disattivata dall\'amministratore"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml
new file mode 100644
index 0000000..fca5986
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"מופעל על ידי מנהל המכשיר"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"הושבת על ידי מנהל המכשיר"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml
new file mode 100644
index 0000000..1c077b6
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"管理者が有効にしました"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"管理者が無効にしました"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ka/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ka/strings.xml
new file mode 100644
index 0000000..9ecf6b3
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ka/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"ჩართულია ადმინისტრატორის მიერ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"გათიშულია ადმინისტრატორის მიერ"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-kk/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-kk/strings.xml
new file mode 100644
index 0000000..552e02e
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-kk/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Әкімші қосқан"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Әкімші өшірген"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-km/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-km/strings.xml
new file mode 100644
index 0000000..aff5d30
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-km/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"បើកដោយ​អ្នកគ្រប់គ្រង"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"បិទដោយអ្នកគ្រប់គ្រង"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-kn/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-kn/strings.xml
new file mode 100644
index 0000000..99bd4d5
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-kn/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ko/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ko/strings.xml
new file mode 100644
index 0000000..d7b0b44
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ko/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"관리자가 사용 설정함"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"관리자가 사용 중지함"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ky/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ky/strings.xml
new file mode 100644
index 0000000..df3b559
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ky/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Администратор иштетип койгон"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Администратор өчүрүп койгон"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-lo/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-lo/strings.xml
new file mode 100644
index 0000000..fca6d1b
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-lo/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"ເປີດນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"ຖືກຜູ້ເບິ່ງແຍງລະບົບປິດໄວ້"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-lt/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-lt/strings.xml
new file mode 100644
index 0000000..0bd27bc
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-lt/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Įgalino administratorius"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Išjungė administratorius"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-lv/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-lv/strings.xml
new file mode 100644
index 0000000..9c5f693
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-lv/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Iespējoja administrators"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Atspējoja administrators"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-mk/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-mk/strings.xml
new file mode 100644
index 0000000..b0fb0a8
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-mk/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Овозможено од администраторот"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Оневозможено од администраторот"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ml/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ml/strings.xml
new file mode 100644
index 0000000..dd9c229
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ml/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"അഡ്‌മിൻ പ്രവർത്തനക്ഷമമാക്കി"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"അഡ്‌മിൻ പ്രവർത്തനരഹിതമാക്കി"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-mn/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-mn/strings.xml
new file mode 100644
index 0000000..d32c2ca
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-mn/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Админ идэвхжүүлсэн"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Админ цуцалсан"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml
new file mode 100644
index 0000000..06fdf6f
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"प्रशासकाने सुरू केलेले"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"प्रशासकाने बंद केलेले"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ms/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ms/strings.xml
new file mode 100644
index 0000000..aabfb7c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ms/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Didayakan oleh pentadbir"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Dilumpuhkan oleh pentadbir"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-my/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-my/strings.xml
new file mode 100644
index 0000000..daa4614
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-my/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"စီမံခန့်ခွဲသူက ဖွင့်ထားသည်"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"စီမံခန့်ခွဲသူက ပိတ်ထားသည်"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-nb/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-nb/strings.xml
new file mode 100644
index 0000000..becbb91
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-nb/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Aktivert av administratoren"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Deaktivert av administratoren"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ne/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ne/strings.xml
new file mode 100644
index 0000000..63ef646
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ne/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"प्रशासकद्वारा सक्षम पारिएको"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"प्रशासकद्वारा असक्षम पारिएको"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-nl/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-nl/strings.xml
new file mode 100644
index 0000000..5d7a85e
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-nl/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Ingeschakeld door beheerder"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Uitgeschakeld door beheerder"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml
new file mode 100644
index 0000000..fee0d39
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ୱାରା ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ଵାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-pa/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-pa/strings.xml
new file mode 100644
index 0000000..2765cabd
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-pa/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-pl/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-pl/strings.xml
new file mode 100644
index 0000000..d9e06b6
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-pl/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Włączone przez administratora"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Wyłączone przez administratora"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rBR/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..1ad4b6b
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rBR/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Ativado pelo administrador"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Desativado pelo administrador"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..f86a73f
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Ativada pelo administrador"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Desativada pelo administrador"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-pt/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-pt/strings.xml
new file mode 100644
index 0000000..1ad4b6b
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-pt/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Ativado pelo administrador"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Desativado pelo administrador"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ro/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ro/strings.xml
new file mode 100644
index 0000000..ff8c2aa
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ro/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Activat de administrator"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Dezactivat de administrator"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ru/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ru/strings.xml
new file mode 100644
index 0000000..d4dfb1c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ru/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Включено администратором"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Отключено администратором"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-si/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-si/strings.xml
new file mode 100644
index 0000000..7c8520b
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-si/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"පරිපාලක විසින් සබල කර ඇත"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"ඔබගේ පරිපාලක විසින් අබල කර ඇත"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-sk/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-sk/strings.xml
new file mode 100644
index 0000000..7a9c1cc
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Povolené správcom"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Zakázané správcom"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-sl/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-sl/strings.xml
new file mode 100644
index 0000000..4926641
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Omogočil skrbnik"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Onemogočil skrbnik"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-sq/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-sq/strings.xml
new file mode 100644
index 0000000..5f9dc59
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-sq/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Aktivizuar nga administratori"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Çaktivizuar nga administratori"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-sr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-sr/strings.xml
new file mode 100644
index 0000000..2d1ac54
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-sr/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Администратор је омогућио"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Администратор је онемогућио"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-sv/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-sv/strings.xml
new file mode 100644
index 0000000..6af3776
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-sv/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Aktiverad av administratör"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Inaktiverad av administratören"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-sw/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-sw/strings.xml
new file mode 100644
index 0000000..08526f8
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-sw/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Imewashwa na msimamizi"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Imezimwa na msimamizi"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ta/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ta/strings.xml
new file mode 100644
index 0000000..405fb7c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ta/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"நிர்வாகி இயக்கியுள்ளார்"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"நிர்வாகி முடக்கியுள்ளார்"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-te/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-te/strings.xml
new file mode 100644
index 0000000..462f02e
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-te/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"నిర్వాహకులు ప్రారంభించారు"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"నిర్వాహకులు నిలిపివేసారు"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-th/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-th/strings.xml
new file mode 100644
index 0000000..e654ba1
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-th/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"เปิดใช้โดยผู้ดูแลระบบ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"ปิดใช้โดยผู้ดูแลระบบ"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-tl/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-tl/strings.xml
new file mode 100644
index 0000000..f80cefa
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Na-enable ng admin"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Na-disable ng admin"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-tr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-tr/strings.xml
new file mode 100644
index 0000000..9dd4713
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-tr/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Yönetici tarafından etkinleştirildi"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Yönetici tarafından devre dışı bırakıldı"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-uk/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-uk/strings.xml
new file mode 100644
index 0000000..5096921
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-uk/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Увімкнено адміністратором"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Вимкнено адміністратором"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ur/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ur/strings.xml
new file mode 100644
index 0000000..7e70936
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ur/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"منتظم کی طرف سے فعال کردہ"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"منتظم کی طرف سے غیر فعال کردہ"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-uz/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-uz/strings.xml
new file mode 100644
index 0000000..a402af6
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-uz/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Administrator tomonidan yoqilgan"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Administrator tomonidan faolsizlantirilgan"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml
new file mode 100644
index 0000000..dd993df
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Do quản trị viên bật"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Bị quản trị viên tắt"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rCN/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..2aab9ac
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"已被管理员启用"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"已被管理员停用"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rHK/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..cb3163a
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rHK/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"已由管理員啟用"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"已由管理員停用"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rTW/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..cb3163a
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-zh-rTW/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"已由管理員啟用"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"已由管理員停用"</string>
+</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-zu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-zu/strings.xml
new file mode 100644
index 0000000..313c9eb
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-zu/strings.xml
@@ -0,0 +1,22 @@
+<?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="enabled_by_admin" msgid="7797093432952898000">"Kunikwe amandla umlawuli"</string>
+    <string name="disabled_by_admin" msgid="1910810467107358241">"Kukhutshazwe umlawuli"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/Android.bp b/packages/SettingsLib/SearchWidget/Android.bp
new file mode 100644
index 0000000..7541ca45
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/Android.bp
@@ -0,0 +1,8 @@
+android_library {
+    name: "SettingsLibSearchWidget",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/SearchWidget/AndroidManifest.xml b/packages/SettingsLib/SearchWidget/AndroidManifest.xml
new file mode 100644
index 0000000..b86544e
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/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.search">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/SearchWidget/res/drawable/ic_search_24dp.xml b/packages/SettingsLib/SearchWidget/res/drawable/ic_search_24dp.xml
new file mode 100644
index 0000000..7e65848
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/drawable/ic_search_24dp.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M20.49,19l-5.73,-5.73C15.53,12.2 16,10.91 16,9.5C16,5.91 13.09,3 9.5,3S3,5.91 3,9.5C3,13.09 5.91,16 9.5,16c1.41,0 2.7,-0.47 3.77,-1.24L19,20.49L20.49,19zM5,9.5C5,7.01 7.01,5 9.5,5S14,7.01 14,9.5S11.99,14 9.5,14S5,11.99 5,9.5z"/>
+</vector>
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/SearchWidget/res/values/strings.xml b/packages/SettingsLib/SearchWidget/res/values/strings.xml
new file mode 100644
index 0000000..0b12810
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values/strings.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.
+  -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Text used as a search hint into the search box [CHAR_LIMIT=60]-->
+    <string name="search_menu">Search settings</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..af30425
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+            android:paddingMode="stack">
+    <item>
+        <shape>
+            <corners
+                android:radius="20dp"/>
+            <stroke
+                android:color="?android:attr/textColorSecondary"
+                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..c26295c
--- /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<CharSequence> extends ArrayAdapter {
+
+    /**
+     * 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/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index aa96444..b77d4e5 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Ingeprop; kan nie op die oomblik laai nie"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Beheer deur administrateur"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Geaktiveer deur administrateur"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Gedeaktiveer deur administrateur"</string>
     <string name="disabled" msgid="9206776641295849915">"Gedeaktiveer"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Toegelaat"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nie toegelaat nie"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 452206c..836ec80 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ተሰክቷል፣ አሁን ኃይል መሙላት አይቻልም"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"በአስተዳዳሪ ነቅቷል"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"በአስተዳዳሪ ተሰናክሏል"</string>
     <string name="disabled" msgid="9206776641295849915">"ቦዝኗል"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ይፈቀዳል"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"አይፈቀድም"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index e67e1ec..5c11db1 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"تم التوصيل، ولكن يتعذّر الشحن الآن"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"إعدادات يتحكم فيها المشرف"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"تم تفعيل الإعداد بواسطة المشرف"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"تم إيقاف الإعداد بواسطة المشرف"</string>
     <string name="disabled" msgid="9206776641295849915">"غير مفعّل"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"مسموح به"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"غير مسموح به"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 7311661..ddd17daf 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"প্লাগ কৰি থোৱা হৈছে, এই মুহূৰ্তত চ্চাৰ্জ কৰিব নোৱাৰি"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"পূৰ্ণ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"এডমিনৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"প্ৰশাসকে সক্ষম কৰিছে"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"এডমিনে অক্ষম কৰিছে ৰাখিছে"</string>
     <string name="disabled" msgid="9206776641295849915">"নিষ্ক্ৰিয়"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"অনুমতি দিয়া হৈছে"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"অনুমতি দিয়া হোৱা নাই"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 750bf5d..a6e484f 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Cihaz hazırda batareya yığa bilmir"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Admin tərəfindən nəzarət olunur"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Admin tərəfindən aktiv edildi"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Admin tərəfindən deaktiv edildi"</string>
     <string name="disabled" msgid="9206776641295849915">"Deaktiv"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"İcazə verilib"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"İcazə verilməyib"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index cd8096c..a446845 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Priključeno je, ali punjenje trenutno nije moguće"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontroliše administrator"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio je administrator"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Administrator je onemogućio"</string>
     <string name="disabled" msgid="9206776641295849915">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Dozvoljeno"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nije dozvoljeno"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 072913a..d56db13 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Падключана да сеткі сілкавання, зарадзіць зараз немагчыма"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Кантралюецца адміністратарам"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Уключана адміністратарам"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Адключана адміністратарам"</string>
     <string name="disabled" msgid="9206776641295849915">"Адключанае"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Дазволена"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Забаронена"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index a5ce523..c1bc31c 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Включена в захранването, в момента не се зарежда"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролира се от администратор"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Активирано от администратора"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Деактивирано от администратора"</string>
     <string name="disabled" msgid="9206776641295849915">"Деактивирано"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Има разрешение"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Няма разрешение"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index c053771..1550c00 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"প্লাগ-ইন করা হয়েছে কিন্তু এখনই চার্জ করা যাবে না"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"প্রশাসক দ্বারা সক্ষম করা হয়েছে"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
     <string name="disabled" msgid="9206776641295849915">"অক্ষম হয়েছে"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"অনুমোদিত"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"অনুমোদিত নয়"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 764bc19..460e7cf 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Priključen, trenutno se ne može puniti"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pod kontrolom administratora"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio administrator"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Onemogućio administrator"</string>
     <string name="disabled" msgid="9206776641295849915">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Dozvoljeno"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nije dozvoljeno"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8309c41a..72dd8cf 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"El dispositiu està endollat però en aquests moments no es pot carregar"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Activada per l\'administrador"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Desactivada per l\'administrador"</string>
     <string name="disabled" msgid="9206776641295849915">"Desactivat"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Amb permís"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Sense permís"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index bd8bc2b..de02245 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Zapojeno, ale nelze nabíjet"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Spravováno administrátorem"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Zapnuto administrátorem"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Zakázáno administrátorem"</string>
     <string name="disabled" msgid="9206776641295849915">"Deaktivováno"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Povoleno"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Není povoleno"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index ab81346..34608d3 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Enheden er tilsluttet en strømkilde. Det er ikke muligt at oplade på nuværende tidspunkt."</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fuldt"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolleret af administratoren"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Aktiveret af administratoren"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Deaktiveret af administratoren"</string>
     <string name="disabled" msgid="9206776641295849915">"Deaktiveret"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Tilladt"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ikke tilladt"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 2432a10..79965d2 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -348,7 +348,7 @@
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Momentan ausgeführte Dienste anzeigen und steuern"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-Implementierung"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-Implementierung festlegen"</string>
-    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Diese Auswahl ist nicht mehr gültig. Versuche es erneut."</string>
+    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Diese Auswahl ist nicht mehr gültig. Bitte versuche es noch einmal."</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Zu Dateiverschlüsselung wechseln"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Wechseln…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Dateiverschlüsselung wird bereits verwendet."</string>
@@ -379,12 +379,12 @@
     <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_remaining_only_more_than_subtext" msgid="8931654680569617380">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend"</string>
-    <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="1181059207608751924">"Smartphone wird möglicherweise bald ausgeschaltet"</string>
-    <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="2606370266981054691">"Tablet wird möglicherweise bald ausgeschaltet"</string>
-    <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="2918084807716859985">"Gerät wird möglicherweise bald ausgeschaltet"</string>
-    <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="3090926004324573908">"Smartphone wird möglicherweise bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet wird möglicherweise bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Gerät wird möglicherweise bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="1181059207608751924">"Smartphone wird eventuell bald ausgeschaltet"</string>
+    <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="2606370266981054691">"Tablet wird eventuell bald ausgeschaltet"</string>
+    <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="2918084807716859985">"Gerät wird eventuell bald ausgeschaltet"</string>
+    <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="3090926004324573908">"Smartphone wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Gerät wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> bis zur vollständigen Aufladung"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig geladen"</string>
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Angeschlossen, kann derzeit nicht geladen werden"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Durch den Administrator verwaltet"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Vom Administrator aktiviert"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Vom Administrator deaktiviert"</string>
     <string name="disabled" msgid="9206776641295849915">"Deaktiviert"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Zulässig"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nicht zulässig"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 6f2889c..b9ea843 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Συνδέθηκε, δεν είναι δυνατή η φόρτιση αυτήν τη στιγμή"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ελέγχονται από το διαχειριστή"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Ενεργοποιήθηκε από τον διαχειριστή"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Απενεργοποιήθηκε από τον διαχειριστή"</string>
     <string name="disabled" msgid="9206776641295849915">"Απενεργοποιημένο"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Επιτρέπεται"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Δεν επιτρέπεται"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 154aa7d..1a7d7c5 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 154aa7d..1a7d7c5 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 154aa7d..1a7d7c5 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 154aa7d..1a7d7c5 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index e9746c0..2bfd5b1 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎Plugged in, can\'t charge right now‎‏‎‎‏‎"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎Full‎‏‎‎‏‎"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎Controlled by admin‎‏‎‎‏‎"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎Enabled by admin‎‏‎‎‏‎"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎Disabled by admin‎‏‎‎‏‎"</string>
     <string name="disabled" msgid="9206776641295849915">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎Disabled‎‏‎‎‏‎"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎Allowed‎‏‎‎‏‎"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Not allowed‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 706e1d3..790c0d3 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Conectado. No se puede cargar en este momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"El administrador habilitó esta opción"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"El administrador inhabilitó esta opción"</string>
     <string name="disabled" msgid="9206776641295849915">"Inhabilitada"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Permitida"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"No permitida"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index f9eddd9..1dec85d 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Se ha conectado, pero no se puede cargar en este momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Habilitada por el administrador"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Inhabilitado por el administrador"</string>
     <string name="disabled" msgid="9206776641295849915">"Inhabilitada"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Autorizadas"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"No autorizadas"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index ac31880..406e15d 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Vooluvõrgus, praegu ei saa laadida"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Juhib administraator"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Administraatori lubatud"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Administraatori keelatud"</string>
     <string name="disabled" msgid="9206776641295849915">"Keelatud"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Lubatud"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Pole lubatud"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 2eee948..bd4724e 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Konektatuta dago. Ezin da kargatu une honetan."</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administratzaileak kontrolatzen du"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Administratzaileak gaitu du"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Administratzaileak desgaitu du"</string>
     <string name="disabled" msgid="9206776641295849915">"Desgaituta"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Baimena dauka"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ez dauka baimenik"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 6efd4fe..45b8ac7 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"به برق وصل شده‌ است، درحال‌حاضر شارژ نمی‌شود"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"توسط سرپرست سیستم کنترل می‌شود"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"فعال‌شده توسط سرپرست"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"غیرفعال‌شده توسط سرپرست"</string>
     <string name="disabled" msgid="9206776641295849915">"غیر فعال شد"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"مجاز"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"مجاز نیست"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 4d64e81..23c63b1 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Kytketty virtalähteeseen, lataaminen ei onnistu"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Järjestelmänvalvojan käyttöön ottama"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Järjestelmänvalvojan estämä"</string>
     <string name="disabled" msgid="9206776641295849915">"Pois käytöstä"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Sallittu"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ei sallittu"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 8e813ea..ad99000 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"L\'appareil est branché, mais il ne peut pas être chargé pour le moment"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Activé par l\'administrateur"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Désactivé par l\'administrateur"</string>
     <string name="disabled" msgid="9206776641295849915">"Désactivée"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Autorisée"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Non autorisée"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index baf8ed0..c23db25 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Appareil branché, mais impossible de le charger pour le moment"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Activé par l\'administrateur"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Désactivé par l\'administrateur"</string>
     <string name="disabled" msgid="9206776641295849915">"Désactivée"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Autorisé"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Non autorisé"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index dc22b25..46532e9 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Conectouse, pero non se pode cargar neste momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Opción controlada polo administrador"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Activado polo administrador"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Desactivado polo administrador"</string>
     <string name="disabled" msgid="9206776641295849915">"Desactivada"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Permitida"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Non permitida"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 7943d51..6a74490 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"પ્લગ ઇન કરેલ, હમણાં ચાર્જ કરી શકતા નથી"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"વ્યવસ્થાપકે સક્ષમ કરેલ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"વ્યવસ્થાપકે અક્ષમ કરેલ"</string>
     <string name="disabled" msgid="9206776641295849915">"અક્ષમ કર્યો"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"મંજૂરી છે"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"મંજૂરી નથી"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 3ec7e58..bd9a6ec 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"प्लग इन है, अभी चार्ज नहीं हो सकती"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"इसका नियंत्रण एडमिन के पास है"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"व्यवस्थापक ने सक्षम किया है"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"व्यवस्थापक ने अक्षम किया है"</string>
     <string name="disabled" msgid="9206776641295849915">"बंद किया गया"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"अनुमति है"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमति नहीं है"</string>
@@ -448,7 +446,6 @@
     <string name="alarm_template_far" msgid="3779172822607461675">"अलार्म <xliff:g id="WHEN">%1$s</xliff:g> को बजेगा"</string>
     <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"अवधि"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"हर बार पूछें"</string>
-    <!-- no translation found for zen_mode_forever (2704305038191592967) -->
-    <skip />
+    <string name="zen_mode_forever" msgid="2704305038191592967">"जब तक आप इसे बंद नहीं करते"</string>
     <string name="time_unit_just_now" msgid="6363336622778342422">"अभी-अभी"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ce8e6ec..5270531 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Uključen, trenutačno se ne može puniti"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolira administrator"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio administrator"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Onemogućio administrator"</string>
     <string name="disabled" msgid="9206776641295849915">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Dopušteno"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nije dopušteno"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 1c79199..ad897f8 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Csatlakoztatva, jelenleg nem tölt"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Rendszergazda által irányítva"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"A rendszergazda bekapcsolta"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"A rendszergazda kikapcsolta"</string>
     <string name="disabled" msgid="9206776641295849915">"Letiltva"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Engedélyezett"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nem engedélyezett"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 84ee039..82755f9 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Միացված է հոսանքի աղբյուրին, սակայն այս պահին չի կարող լիցքավորվել"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված է"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Միացված է ադմինիստրատորի կողմից"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Անջատվել է ադմինիստրատորի կողմից"</string>
     <string name="disabled" msgid="9206776641295849915">"Կասեցված է"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Թույլատրված է"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Արգելված է"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 9356c85..961f892 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Tercolok, tidak dapat mengisi baterai sekarang"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikontrol oleh admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Diaktifkan oleh admin"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Dinonaktifkan oleh admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Dinonaktifkan"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Diizinkan"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Tidak diizinkan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index ca5e1f5..759b7ba 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Í sambandi, ekki hægt að hlaða eins og er"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Stjórnað af kerfisstjóra"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Gert virkt af kerfisstjóra"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Gert óvirkt af kerfisstjóra"</string>
     <string name="disabled" msgid="9206776641295849915">"Óvirkt"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Heimilað"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ekki heimilað"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 88a5bb8..bd41e28 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Collegato alla corrente. Impossibile caricare al momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Gestita dall\'amministratore"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Attivata dall\'amministratore"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Disattivata dall\'amministratore"</string>
     <string name="disabled" msgid="9206776641295849915">"Disattivato"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Consentite"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Non consentite"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index cec35cf..5a11e72 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"המכשיר מחובר, אבל לא ניתן לטעון עכשיו"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"מופעל על ידי מנהל המכשיר"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"הושבת על ידי מנהל המכשיר"</string>
     <string name="disabled" msgid="9206776641295849915">"מושבת"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"מורשה"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"לא מורשה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 9cfdadc..f6b81ed 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"接続されていますが、現在、充電できません"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"フル"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"管理者により管理されています"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"管理者により有効にされています"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"管理者により無効にされています"</string>
     <string name="disabled" msgid="9206776641295849915">"無効"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"許可"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"許可しない"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 1083025..d5f5408 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"მიერთებულია, დატენვა ამჟამად ვერ ხერხდება"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"იმართება ადმინისტრატორის მიერ"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"ჩართულია ადმინისტრატორის მიერ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"გათიშულია ადმინისტრატორის მიერ"</string>
     <string name="disabled" msgid="9206776641295849915">"გამორთული"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"დაშვებულია"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"დაუშვებელია"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index a122d91..c3fbfcd 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Қосылған, зарядталмайды"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Толы"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Әкімші басқарады"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Әкімші қосқан"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Әкімші өшірген"</string>
     <string name="disabled" msgid="9206776641295849915">"Өшірілген"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Рұқсат етілген"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Рұқсат етілмеген"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 7ffd766..8e73f81 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ដោត​សាកថ្ម​រួចហើយ ប៉ុន្តែ​​សាកថ្ម​មិន​ចូលទេឥឡូវនេះ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"បើកដោយ​អ្នកគ្រប់គ្រង"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"បិទដោយអ្នកគ្រប់គ្រង"</string>
     <string name="disabled" msgid="9206776641295849915">"បិទ"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"បាន​អនុញ្ញាត"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"មិន​អនុញ្ញាត​ទេ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index e12cbd2..ce225ea 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆ, ಇದೀಗ ಚಾರ್ಜ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
     <string name="disabled" msgid="9206776641295849915">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ಅನುಮತಿಸಲಾಗಿದೆ"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index d29bd65..b47471b 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"전원이 연결되었지만 현재 충전할 수 없음"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"관리자가 제어"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"관리자가 사용 설정함"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"관리자가 사용 중지함"</string>
     <string name="disabled" msgid="9206776641295849915">"사용 안함"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"허용됨"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"허용되지 않음"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 56b5da1..9853dac 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Сайылып турат, учурда кубаттоо мүмкүн эмес"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Администратор тарабынан көзөмөлдөнөт"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Администратор иштетип койгон"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Администратор өчүрүп койгон"</string>
     <string name="disabled" msgid="9206776641295849915">"Өчүрүлгөн"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Уруксат берилген"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Тыюу салынган"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index eb27f02..1816515 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ສຽບສາຍແລ້ວ, ບໍ່ສາມາດສາກໄດ້ໃນຕອນນີ້"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"ຜູ້ເບິ່ງແຍງລະບົບເປີດໃຫ້ໃຊ້ແລ້ວ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"ຖືກຜູ້ເບິ່ງແຍງລະບົບປິດໄວ້"</string>
     <string name="disabled" msgid="9206776641295849915">"ປິດການນຳໃຊ້"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ອະນຸຍາດແລ້ວ"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ບໍ່ອະນຸຍາດແລ້ວ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 44b532b..e6a8e1c 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Įjungta į maitinimo lizdą, bet šiuo metu įkrauti neįmanoma"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Valdo administratorius"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Įgalino administratorius"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Išjungė administratorius"</string>
     <string name="disabled" msgid="9206776641295849915">"Neleidžiama"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Leidžiama"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Neleidžiama"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index ba87d07..b55afc0 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Pievienots, taču pašlaik nevar veikt uzlādi"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolē administrators"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Iespējoja administrators"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Atspējoja administrators"</string>
     <string name="disabled" msgid="9206776641295849915">"Atspējots"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Atļauts"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nav atļauts"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 0c5c94a..e28c8ee 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Приклучен е, но батеријата не може да се полни во моментов"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Полна"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролирано од администраторот"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Овозможено од администраторот"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Оневозможено од администраторот"</string>
     <string name="disabled" msgid="9206776641295849915">"Оневозможено"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Дозволено"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Не е дозволено"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 1a208e62..6860398 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"പ്ലഗ് ഇൻ ചെയ്‌തു, ഇപ്പോൾ ചാർജ് ചെയ്യാനാവില്ല"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"അഡ്‌മിൻ നിയന്ത്രിക്കുന്നത്"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"അഡ്‌മിൻ പ്രവർത്തനക്ഷമമാക്കി"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"അഡ്‌മിൻ പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="disabled" msgid="9206776641295849915">"പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"അനുവദനീയം"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"അനുവദിച്ചിട്ടില്ല"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 809e82e..ba6d601 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Залгаастай тул одоо цэнэглэх боломжгүй"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Админ удирдсан"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Админ идэвхжүүлсэн"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Админ цуцалсан"</string>
     <string name="disabled" msgid="9206776641295849915">"Идэвхгүйжүүлсэн"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Зөвшөөрсөн"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Зөвшөөрөөгүй"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index dfa6d2f..a5d230a 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"प्लग इन केलेले आहे, आता चार्ज करू शकत नाही"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकाने नियंत्रित केलेले"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"प्रशासकाने सक्षम केलेले"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"प्रशासकाने अक्षम केलेले"</string>
     <string name="disabled" msgid="9206776641295849915">"अक्षम"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"अनुमती आहे"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमती नाही"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index b4ed016..a7ac3ef 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Dipalamkan, tidak boleh mengecas sekarang"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikawal oleh pentadbir"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Didayakan oleh pentadbir"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Dilumpuhkan oleh pentadbir"</string>
     <string name="disabled" msgid="9206776641295849915">"Dilumpuhkan"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Dibenarkan"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Tidak dibenarkan"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index c1ffd28..6cdab67 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ပလပ်ထိုးထားသောကြောင့် ယခုအားသွင်း၍ မရသေးပါ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"စီမံခန့်ခွဲသူက ဖွင့်ထားသည်"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"စီမံခန့်ခွဲသူက ပိတ်ထားသည်"</string>
     <string name="disabled" msgid="9206776641295849915">"ပိတ်ထားပြီး"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ခွင့်ပြုထားသည်"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ခွင့်မပြုပါ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 5a8e01e..cf18477 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Laderen er koblet til – kan ikke lade akkurat nå"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrollert av administratoren"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Slått på av administratoren"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Avslått av administratoren"</string>
     <string name="disabled" msgid="9206776641295849915">"Slått av"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Tillatt"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ikke tillatt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 72a9abb..8aba0f8 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"प्लगइन गरिएको छ, अहिले नै चार्ज गर्न सकिँदैन"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण चार्ज भएको स्थिति"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकद्वारा नियन्त्रित"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"प्रशासकद्वारा सक्षम पारिएको छ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"प्रशासकद्वारा असक्षम पारिएको छ"</string>
     <string name="disabled" msgid="9206776641295849915">"असक्षम पारियो"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"अनुमति छ"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमति छैन"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index f341717..e3f1aea 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Aangesloten, kan nu niet opladen"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ingesteld door beheerder"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Ingeschakeld door beheerder"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Uitgeschakeld door beheerder"</string>
     <string name="disabled" msgid="9206776641295849915">"Uitgeschakeld"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Toegestaan"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Niet toegestaan"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index a7761e9..8ecac4d 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ପ୍ଲଗ୍‌ରେ ଲାଗିଛି, ହେଲେ ଏବେ ଚାର୍ଜ କରିପାରିବ ନାହିଁ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ଚାର୍ଜ ଅଛି"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"ଆଡମିନ୍‌ଙ୍କ ଦ୍ୱାରା ସକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"ଆଡ୍‌ମିନ୍‌ ଦ୍ଵାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="disabled" msgid="9206776641295849915">"ଅକ୍ଷମ ହୋଇଛି"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ଅନୁମୋଦିତ"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ଅନୁମତି ନାହିଁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index c7ab379..6f17e13 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ਪਲੱਗ ਲੱਗਾ ਹੋਇਆ ਹੈ, ਇਸ ਸਮੇਂ ਚਾਰਜ ਨਹੀਂ ਹੋ ਸਕਦੀ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
     <string name="disabled" msgid="9206776641295849915">"ਅਯੋਗ ਬਣਾਇਆ"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ਇਜਾਜ਼ਤ ਹੈ"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ਇਜਾਜ਼ਤ ਨਹੀਂ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index effa59a..3c208e3 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Podłączony. Nie można teraz ładować"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolowane przez administratora"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Włączone przez administratora"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Wyłączone przez administratora"</string>
     <string name="disabled" msgid="9206776641295849915">"Wyłączone"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Dozwolone"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Niedozwolone"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index afefeda..5c363a4 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Conectado. Não é possível carregar no momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Carregada"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Ativado pelo administrador"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo administrador"</string>
     <string name="disabled" msgid="9206776641295849915">"Desativado"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Permitido"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Não permitido"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 4ee4521..66c59ac 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Ligada à corrente, não é possível carregar neste momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo gestor"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Ativada pelo gestor"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo gestor"</string>
     <string name="disabled" msgid="9206776641295849915">"Desativada"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Autorizada"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Não autorizada"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index afefeda..5c363a4 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Conectado. Não é possível carregar no momento"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Carregada"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Ativado pelo administrador"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo administrador"</string>
     <string name="disabled" msgid="9206776641295849915">"Desativado"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Permitido"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Não permitido"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index f42363e..703add6 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Conectat, nu se poate încărca chiar acum"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlată de administrator"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Activat de administrator"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Dezactivat de administrator"</string>
     <string name="disabled" msgid="9206776641295849915">"Dezactivată"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Permise"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nepermise"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 451c710..4eb3ca4 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Подключено, не заряжается"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролируется администратором"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Включено администратором"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Отключено администратором"</string>
     <string name="disabled" msgid="9206776641295849915">"Отключено"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Разрешено"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Запрещено"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index d9e69ce..1ab5b79 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"පේනුගත කර ඇත, මේ අවස්ථාවේදී ආරෝපණය කළ නොහැකිය"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"පරිපාලක විසින් පාලනය කරන ලදී"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"පරිපාලක විසින් සබල කර ඇත"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"ඔබගේ පරිපාලක විසින් අබල කර ඇත"</string>
     <string name="disabled" msgid="9206776641295849915">"අබල කර ඇත"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"ඉඩ දුන්"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ඉඩ නොදෙන"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index a0c1062..5c3920f 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Pripojené, ale nie je možné nabíjať"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ovládané správcom"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Povolené správcom"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Zakázané správcom"</string>
     <string name="disabled" msgid="9206776641295849915">"Deaktivované"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Povolené"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nie je povolené"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 3088d0f..f479405 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Priključeno, trenutno ni mogoče polniti"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Nadzira skrbnik"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Omogočil skrbnik"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Onemogočil skrbnik"</string>
     <string name="disabled" msgid="9206776641295849915">"Onemogočeno"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Dovoljene"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ni dovoljeno"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 8e31013..2741985 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Në prizë, por nuk mund të ngarkohet për momentin"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolluar nga administratori"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Aktivizuar nga administratori"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Çaktivizuar nga administratori"</string>
     <string name="disabled" msgid="9206776641295849915">"Çaktivizuar"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Lejohet"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Nuk lejohet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index fe97119..241d9cb 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Прикључено је, али пуњење тренутно није могуће"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Пуна"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролише администратор"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Омогућио је администратор"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Администратор је онемогућио"</string>
     <string name="disabled" msgid="9206776641295849915">"Онемогућено"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Дозвољено"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Није дозвољено"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 11f446c..d338e96 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Inkopplad, kan inte laddas just nu"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Strys av administratören"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Aktiverad av administratör"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Inaktiverad av administratören"</string>
     <string name="disabled" msgid="9206776641295849915">"Inaktiverad"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Tillåts"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Tillåts inte"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index ba3aaba..df122e2 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Haiwezi kuchaji kwa sasa"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Imedhibitiwa na msimamizi"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Imewashwa na msimamizi"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Imezimwa na msimamizi"</string>
     <string name="disabled" msgid="9206776641295849915">"Imezimwa"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Imeruhusiwa"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Hairuhusiwi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 63d5e75..8f5c7d8 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"செருகப்பட்டது, ஆனால் இப்போது சார்ஜ் செய்ய முடியவில்லை"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"முழுவதும் சார்ஜ் ஆனது"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"நிர்வாகி இயக்கியுள்ளார்"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"நிர்வாகி முடக்கியுள்ளார்"</string>
     <string name="disabled" msgid="9206776641295849915">"முடக்கப்பட்டது"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"அனுமதிக்கப்பட்டது"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"அனுமதிக்கப்படவில்லை"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 4af461d..5f7ab996 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ప్లగ్ ఇన్ చేయబడింది, ప్రస్తుతం ఛార్జ్ చేయడం సాధ్యం కాదు"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"నిర్వాహకులు ప్రారంభించారు"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"నిర్వాహకులు నిలిపివేసారు"</string>
     <string name="disabled" msgid="9206776641295849915">"నిలిపివేయబడింది"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"అనుమతించినవి"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"అనుమతించబడలేదు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 9cc5c73..020baf0 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"เสียบอยู่ ไม่สามารถชาร์จได้ในขณะนี้"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"เปิดใช้โดยผู้ดูแลระบบ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"ปิดใช้โดยผู้ดูแลระบบ"</string>
     <string name="disabled" msgid="9206776641295849915">"ปิดอยู่"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"อนุญาต"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"ไม่อนุญาต"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 49abe42..2164ade 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Nakasaksak, hindi makapag-charge sa ngayon"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pinapamahalaan ng admin"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Na-enable ng admin"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Na-disable ng admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Naka-disable"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Pinapayagan"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Hindi pinapayagan"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 23a96d9..532927c 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Prize takıldı, şu anda şarj olamıyor"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Yönetici tarafından denetleniyor"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Yönetici tarafından etkinleştirildi"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Yönetici devre dışı bıraktı"</string>
     <string name="disabled" msgid="9206776641295849915">"Devre dışı"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"İzin verildi"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"İzin verilmiyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index cea870a4..cf26d20 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Підключено. Не вдається зарядити"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Керується адміністратором"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Увімкнено адміністратором"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Вимкнено адміністратором"</string>
     <string name="disabled" msgid="9206776641295849915">"Вимкнено"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Дозволено"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Заборонено"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 0fb60d9..c158179 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"پلگ ان ہے، ابھی چارج نہیں کر سکتے"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"کنٹرول کردہ بذریعہ منتظم"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"منتظم کی طرف سے فعال کردہ"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"منتظم کی طرف سے غیر فعال کردہ"</string>
     <string name="disabled" msgid="9206776641295849915">"غیر فعال"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"اجازت ہے"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"اجازت نہیں ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 4690db3..ac8bffe 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Ulangan, lekin quvvat olmayapti"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administrator tomonidan boshqariladi"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Administrator tomonidan yoqilgan"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Administrator tomonidan o‘chirilgan"</string>
     <string name="disabled" msgid="9206776641295849915">"O‘chiq"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Ruxsat berilgan"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Ruxsat berilmagan"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 937b37d..78306da 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Đã cắm nhưng không thể sạc ngay"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Do quản trị viên kiểm soát"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Kích hoạt bởi quản trị viên"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Bị quản trị viên vô hiệu hóa"</string>
     <string name="disabled" msgid="9206776641295849915">"Đã tắt"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Được phép"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Không được phép"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 47753fd..4fb26100 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"已插入电源,但是现在无法充电"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"由管理员控制"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"已被管理员启用"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"已被管理员停用"</string>
     <string name="disabled" msgid="9206776641295849915">"已停用"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"允许"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"不允许"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 4cbf5a6..c5a8f92 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"已插入電源插座,但目前無法充電"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"已由管理員啟用"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"已由管理員停用"</string>
     <string name="disabled" msgid="9206776641295849915">"已停用"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"允許"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"不允許"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index cecc6ac..0947ccec 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"已接上電源,但現在無法充電"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"已由管理員啟用"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"已由管理員停用"</string>
     <string name="disabled" msgid="9206776641295849915">"已停用"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"允許"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"不允許"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 94c3abf..cd90d74 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -395,8 +395,6 @@
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Kuxhunyiwe, ayikwazi ukushaja khona manje"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kulawulwa umqondisi"</string>
-    <string name="enabled_by_admin" msgid="5302986023578399263">"Kunikwe amandla umlawuli"</string>
-    <string name="disabled_by_admin" msgid="8505398946020816620">"Kukhutshazwe umlawuli"</string>
     <string name="disabled" msgid="9206776641295849915">"Akusebenzi"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"Kuvumelekile"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"Akuvumelekile"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 332ced6..508adbd 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1116,4 +1116,6 @@
     <!-- time label for event have that happened very recently [CHAR LIMIT=60] -->
     <string name="time_unit_just_now">Just now</string>
 
-  </resources>
+    <!-- The notice header of Third-party licenses. not translatable -->
+    <string name="notice_header" translatable="false"></string>
+</resources>
diff --git a/packages/SettingsLib/search/Android.mk b/packages/SettingsLib/search/Android.mk
index cb19891..14f9626 100644
--- a/packages/SettingsLib/search/Android.mk
+++ b/packages/SettingsLib/search/Android.mk
@@ -5,6 +5,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_RESOURCE_DIR := \
+    $(LOCAL_PATH)/main/res
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index a710410..58feef5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -102,7 +102,7 @@
                 BluetoothProfile.A2DP);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index e13e566..988062d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -96,7 +96,7 @@
                 BluetoothProfile.A2DP_SINK);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b9f7323..750a843 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -29,16 +29,15 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import androidx.annotation.VisibleForTesting;
-
 import com.android.settingslib.R;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 
+import androidx.annotation.VisibleForTesting;
+
 /**
  * CachedBluetoothDevice represents a remote Bluetooth device. It contains
  * attributes of the device (such as the address, name, RSSI, etc.) and
@@ -48,6 +47,10 @@
 public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
     private static final String TAG = "CachedBluetoothDevice";
 
+    // See mConnectAttempted
+    private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
+    private static final long MAX_HOGP_DELAY_FOR_AUTO_CONNECT = 30000;
+
     private final Context mContext;
     private final BluetoothAdapter mLocalAdapter;
     private final LocalBluetoothProfileManager mProfileManager;
@@ -55,7 +58,6 @@
     private long mHiSyncId;
     // Need this since there is no method for getting RSSI
     private short mRssi;
-    private HashMap<LocalBluetoothProfile, Integer> mProfileConnectionState;
 
     private final List<LocalBluetoothProfile> mProfiles =
             new ArrayList<LocalBluetoothProfile>();
@@ -78,17 +80,6 @@
 
     private final static String MESSAGE_REJECTION_COUNT_PREFS_NAME = "bluetooth_message_reject";
 
-    public long getHiSyncId() {
-        return mHiSyncId;
-    }
-
-    public void setHiSyncId(long id) {
-        if (BluetoothUtils.D) {
-            Log.d(TAG, "setHiSyncId: mDevice " + mDevice + ", id " + id);
-        }
-        mHiSyncId = id;
-    }
-
     /**
      * Last time a bt profile auto-connect was attempted.
      * If an ACTION_UUID intent comes in within
@@ -97,14 +88,21 @@
      */
     private long mConnectAttempted;
 
-    // See mConnectAttempted
-    private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
-    private static final long MAX_HOGP_DELAY_FOR_AUTO_CONNECT = 30000;
-
     // Active device state
     private boolean mIsActiveDeviceA2dp = false;
     private boolean mIsActiveDeviceHeadset = false;
     private boolean mIsActiveDeviceHearingAid = false;
+
+    CachedBluetoothDevice(Context context, LocalBluetoothProfileManager profileManager,
+            BluetoothDevice device) {
+        mContext = context;
+        mLocalAdapter = BluetoothAdapter.getDefaultAdapter();
+        mProfileManager = profileManager;
+        mDevice = device;
+        fillData();
+        mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
+    }
+
     /**
      * Describes the current device and profile for logging.
      *
@@ -133,7 +131,6 @@
             }
             return;
         }
-        mProfileConnectionState.put(profile, newProfileState);
         if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
             if (profile instanceof MapProfile) {
                 profile.setPreferred(mDevice, true);
@@ -161,18 +158,6 @@
         fetchActiveDevices();
     }
 
-    CachedBluetoothDevice(Context context,
-                          LocalBluetoothProfileManager profileManager,
-                          BluetoothDevice device) {
-        mContext = context;
-        mLocalAdapter = BluetoothAdapter.getDefaultAdapter();
-        mProfileManager = profileManager;
-        mDevice = device;
-        mProfileConnectionState = new HashMap<LocalBluetoothProfile, Integer>();
-        fillData();
-        mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
-    }
-
     public void disconnect() {
         for (LocalBluetoothProfile profile : mProfiles) {
             disconnect(profile);
@@ -204,6 +189,17 @@
         connectWithoutResettingTimer(connectAllProfiles);
     }
 
+    public long getHiSyncId() {
+        return mHiSyncId;
+    }
+
+    public void setHiSyncId(long id) {
+        if (BluetoothUtils.D) {
+            Log.d(TAG, "setHiSyncId: mDevice " + mDevice + ", id " + id);
+        }
+        mHiSyncId = id;
+    }
+
     void onBondingDockConnect() {
         // Attempt to connect if UUIDs are available. Otherwise,
         // we will connect when the ACTION_UUID intent arrives.
@@ -226,7 +222,7 @@
 
         int preferredProfiles = 0;
         for (LocalBluetoothProfile profile : mProfiles) {
-            if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
+            if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) {
                 if (profile.isPreferred(mDevice)) {
                     ++preferredProfiles;
                     connectInt(profile);
@@ -300,14 +296,6 @@
         return true;
     }
 
-    /**
-     * Return true if user initiated pairing on this device. The message text is
-     * slightly different for local vs. remote initiated pairing dialogs.
-     */
-    boolean isUserInitiatedPairing() {
-        return mDevice.isBondingInitiatedLocally();
-    }
-
     public void unpair() {
         int state = getBondState();
 
@@ -332,22 +320,9 @@
     }
 
     public int getProfileConnectionState(LocalBluetoothProfile profile) {
-        if (mProfileConnectionState.get(profile) == null) {
-            // If cache is empty make the binder call to get the state
-            int state = profile.getConnectionStatus(mDevice);
-            mProfileConnectionState.put(profile, state);
-        }
-        return mProfileConnectionState.get(profile);
-    }
-
-    public void clearProfileConnectionState ()
-    {
-        if (BluetoothUtils.D) {
-            Log.d(TAG," Clearing all connection state for dev:" + mDevice.getName());
-        }
-        for (LocalBluetoothProfile profile :getProfiles()) {
-            mProfileConnectionState.put(profile, BluetoothProfile.STATE_DISCONNECTED);
-        }
+        return profile != null
+                ? profile.getConnectionStatus(mDevice)
+                : BluetoothProfile.STATE_DISCONNECTED;
     }
 
     // TODO: do any of these need to run async on a background thread?
@@ -669,7 +644,7 @@
         List<LocalBluetoothProfile> connectableProfiles =
                 new ArrayList<LocalBluetoothProfile>();
         for (LocalBluetoothProfile profile : mProfiles) {
-            if (profile.isConnectable()) {
+            if (profile.accessProfileEnabled()) {
                 connectableProfiles.add(profile);
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 5a64e02..21cf0c2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -285,11 +285,6 @@
                     {
                         mCachedDevicesMapForHearingAids.remove(cachedDevice.getHiSyncId());
                     }
-                } else {
-                    // For bonded devices, we need to clear the connection status so that
-                    // when BT is enabled next time, device connection status shall be retrieved
-                    // by making a binder call.
-                    cachedDevice.clearProfileConnectionState();
                 }
             }
             for (int i = mHearingAidDevicesNotAddedInCache.size() - 1; i >= 0; i--) {
@@ -297,11 +292,6 @@
                 if (notCachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
                     notCachedDevice.setJustDiscovered(false);
                     mHearingAidDevicesNotAddedInCache.remove(i);
-                } else {
-                    // For bonded devices, we need to clear the connection status so that
-                    // when BT is enabled next time, device connection status shall be retrieved
-                    // by making a binder call.
-                    notCachedDevice.clearProfileConnectionState();
                 }
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index 2dd8eaf..62507f5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -103,7 +103,7 @@
                 BluetoothProfile.HEADSET);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index 1eeb4f0..8bc0acf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -100,7 +100,7 @@
                 new HearingAidServiceListener(), BluetoothProfile.HEARING_AID);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return false;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index 4b6a22c..4879144 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -104,7 +104,7 @@
     }
 
     @Override
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
index c8d4fc8..61e5b6b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
@@ -94,7 +94,7 @@
     }
 
     @Override
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index fe6b222..75d16db 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -93,7 +93,7 @@
                 BluetoothProfile.HID_HOST);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
index 0447f37..4b0ca74 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
@@ -26,9 +26,9 @@
 public interface LocalBluetoothProfile {
 
     /**
-     * Returns true if the user can initiate a connection, false otherwise.
+     * Return {@code true} if the user can initiate a connection for this profile in UI.
      */
-    boolean isConnectable();
+    boolean accessProfileEnabled();
 
     /**
      * Returns true if the user can enable auto connection for this profile.
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 7000f9d..9653972 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -30,6 +30,7 @@
 import android.bluetooth.BluetoothPan;
 import android.bluetooth.BluetoothPbap;
 import android.bluetooth.BluetoothPbapClient;
+import android.bluetooth.BluetoothSap;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
 import android.content.Context;
@@ -98,6 +99,7 @@
     private PbapClientProfile mPbapClientProfile;
     private PbapServerProfile mPbapProfile;
     private HearingAidProfile mHearingAidProfile;
+    private SapProfile mSapProfile;
 
     /**
      * Mapping from profile name, e.g. "HEADSET" to profile object.
@@ -210,6 +212,13 @@
             addProfile(mPbapClientProfile, PbapClientProfile.NAME,
                     BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
         }
+        if (mSapProfile == null && supportedList.contains(BluetoothProfile.SAP)) {
+            if (DEBUG) {
+                Log.d(TAG, "Adding local SAP profile");
+            }
+            mSapProfile = new SapProfile(mContext, mDeviceManager, this);
+            addProfile(mSapProfile, SapProfile.NAME, BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);
+        }
         mEventManager.registerProfileIntentReceiver();
     }
 
@@ -290,10 +299,11 @@
                 }
             }
 
-            mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
-                    mProfile.getProfileId());
             cachedDevice.onProfileStateChanged(mProfile, newState);
             cachedDevice.refresh();
+            // Dispatch profile changed after device update
+            mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
+                    mProfile.getProfileId());
         }
     }
 
@@ -549,6 +559,11 @@
             removedProfiles.remove(mHearingAidProfile);
         }
 
+        if (mSapProfile != null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.SAP)) {
+            profiles.add(mSapProfile);
+            removedProfiles.remove(mSapProfile);
+        }
+
         if (DEBUG) {
             Log.d(TAG,"New Profiles" + profiles.toString());
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
index 7ad2e28c..1e22f44 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -105,7 +105,7 @@
                 new MapClientServiceListener(), BluetoothProfile.MAP_CLIENT);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index caea04f..7582024 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -104,7 +104,7 @@
                 BluetoothProfile.MAP);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
index dfd1622..e1e5dbe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
@@ -32,7 +32,7 @@
     // Order of this profile in device profiles list
     private static final int ORDINAL = 2;
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return false;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index 02afe8d..7b81162 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -78,7 +78,7 @@
             BluetoothProfile.PAN);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index b295f24..1f15601 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -34,7 +34,6 @@
 
 public final class PbapClientProfile implements LocalBluetoothProfile {
     private static final String TAG = "PbapClientProfile";
-    private static boolean V = false;
 
     private BluetoothPbapClient mService;
     private boolean mIsProfileReady;
@@ -56,9 +55,7 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) {
-                Log.d(TAG,"Bluetooth service connected");
-            }
+            Log.d(TAG, "Bluetooth service connected, profile:" + profile);
             mService = (BluetoothPbapClient) proxy;
             // We just bound to the service, so refresh the UI for any connected PBAP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -77,9 +74,7 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) {
-                Log.d(TAG,"Bluetooth service disconnected");
-            }
+            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
             mIsProfileReady = false;
         }
     }
@@ -112,7 +107,7 @@
                 new PbapClientServiceListener(), BluetoothProfile.PBAP_CLIENT);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
@@ -131,31 +126,16 @@
     }
 
     public boolean connect(BluetoothDevice device) {
-        if (V) {
-            Log.d(TAG,"PBAPClientProfile got connect request");
-        }
+        Log.d(TAG,"PBAPClientProfile got connect request");
         if (mService == null) {
             return false;
         }
-        List<BluetoothDevice> srcs = getConnectedDevices();
-        if (srcs != null) {
-            for (BluetoothDevice src : srcs) {
-                if (src.equals(device)) {
-                    // Connect to same device, Ignore it
-                    Log.d(TAG,"Ignoring Connect");
-                    return true;
-                }
-            }
-        }
         Log.d(TAG,"PBAPClientProfile attempting to connect to " + device.getAddress());
-
         return mService.connect(device);
     }
 
     public boolean disconnect(BluetoothDevice device) {
-        if (V) {
-            Log.d(TAG,"PBAPClientProfile got disconnect request");
-        }
+        Log.d(TAG,"PBAPClientProfile got disconnect request");
         if (mService == null) {
             return false;
         }
@@ -218,9 +198,7 @@
     }
 
     protected void finalize() {
-        if (V) {
-            Log.d(TAG, "finalize()");
-        }
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index e9d8cb5..adef0841 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -80,7 +80,7 @@
         BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener());
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
index 61602c6..b4acc48 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
@@ -36,12 +36,10 @@
  */
 final class SapProfile implements LocalBluetoothProfile {
     private static final String TAG = "SapProfile";
-    private static boolean V = true;
 
     private BluetoothSap mService;
     private boolean mIsProfileReady;
 
-    private final LocalBluetoothAdapter mLocalAdapter;
     private final CachedBluetoothDeviceManager mDeviceManager;
     private final LocalBluetoothProfileManager mProfileManager;
 
@@ -59,7 +57,7 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
+            Log.d(TAG, "Bluetooth service connected, profile:" + profile);
             mService = (BluetoothSap) proxy;
             // We just bound to the service, so refresh the UI for any connected SAP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -81,7 +79,7 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
+            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
             mProfileManager.callServiceDisconnectedListeners();
             mIsProfileReady=false;
         }
@@ -96,17 +94,15 @@
         return BluetoothProfile.SAP;
     }
 
-    SapProfile(Context context, LocalBluetoothAdapter adapter,
-            CachedBluetoothDeviceManager deviceManager,
+    SapProfile(Context context, CachedBluetoothDeviceManager deviceManager,
             LocalBluetoothProfileManager profileManager) {
-        mLocalAdapter = adapter;
         mDeviceManager = deviceManager;
         mProfileManager = profileManager;
-        mLocalAdapter.getProfileProxy(context, new SapServiceListener(),
+        BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new SapServiceListener(),
                 BluetoothProfile.SAP);
     }
 
-    public boolean isConnectable() {
+    public boolean accessProfileEnabled() {
         return true;
     }
 
@@ -115,50 +111,47 @@
     }
 
     public boolean connect(BluetoothDevice device) {
-        if (mService == null) return false;
-        List<BluetoothDevice> sinks = mService.getConnectedDevices();
-        if (sinks != null) {
-            for (BluetoothDevice sink : sinks) {
-                mService.disconnect(sink);
-            }
+        if (mService == null) {
+            return false;
         }
         return mService.connect(device);
     }
 
     public boolean disconnect(BluetoothDevice device) {
-        if (mService == null) return false;
-        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
-        if (!deviceList.isEmpty() && deviceList.get(0).equals(device)) {
-            if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-            }
-            return mService.disconnect(device);
-        } else {
+        if (mService == null) {
             return false;
         }
+        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        }
+        return mService.disconnect(device);
     }
 
     public int getConnectionStatus(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
-        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
-
-        return !deviceList.isEmpty() && deviceList.get(0).equals(device)
-                ? mService.getConnectionState(device)
-                : BluetoothProfile.STATE_DISCONNECTED;
+        if (mService == null) {
+            return BluetoothProfile.STATE_DISCONNECTED;
+        }
+        return mService.getConnectionState(device);
     }
 
     public boolean isPreferred(BluetoothDevice device) {
-        if (mService == null) return false;
+        if (mService == null) {
+            return false;
+        }
         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
     }
 
     public int getPreferred(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+        if (mService == null) {
+            return BluetoothProfile.PRIORITY_OFF;
+        }
         return mService.getPriority(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
-        if (mService == null) return;
+        if (mService == null) {
+            return;
+        }
         if (preferred) {
             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -169,7 +162,9 @@
     }
 
     public List<BluetoothDevice> getConnectedDevices() {
-        if (mService == null) return new ArrayList<BluetoothDevice>(0);
+        if (mService == null) {
+            return new ArrayList<BluetoothDevice>(0);
+        }
         return mService.getDevicesMatchingConnectionStates(
               new int[] {BluetoothProfile.STATE_CONNECTED,
                          BluetoothProfile.STATE_CONNECTING,
@@ -207,11 +202,11 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.SAP,
-                                                                       mService);
+                        mService);
                 mService = null;
             }catch (Throwable t) {
                 Log.w(TAG, "Error cleaning up SAP proxy", t);
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
index 42306f6..9db4a35 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
@@ -46,7 +46,7 @@
  * TODO: Remove duplicate codes once backward support ends.
  */
 class LicenseHtmlGeneratorFromXml {
-    private static final String TAG = "LicenseHtmlGeneratorFromXml";
+    private static final String TAG = "LicenseGeneratorFromXml";
 
     private static final String TAG_ROOT = "licenses";
     private static final String TAG_FILE_NAME = "file-name";
@@ -107,12 +107,13 @@
         mXmlFiles = xmlFiles;
     }
 
-    public static boolean generateHtml(List<File> xmlFiles, File outputFile) {
+    public static boolean generateHtml(List<File> xmlFiles, File outputFile,
+            String noticeHeader) {
         LicenseHtmlGeneratorFromXml genertor = new LicenseHtmlGeneratorFromXml(xmlFiles);
-        return genertor.generateHtml(outputFile);
+        return genertor.generateHtml(outputFile, noticeHeader);
     }
 
-    private boolean generateHtml(File outputFile) {
+    private boolean generateHtml(File outputFile, String noticeHeader) {
         for (File xmlFile : mXmlFiles) {
             parse(xmlFile);
         }
@@ -125,7 +126,8 @@
         try {
             writer = new PrintWriter(outputFile);
 
-            generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer);
+            generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer,
+                noticeHeader);
 
             writer.flush();
             writer.close();
@@ -239,13 +241,18 @@
 
     @VisibleForTesting
     static void generateHtml(Map<String, String> fileNameToContentIdMap,
-            Map<String, String> contentIdToFileContentMap, PrintWriter writer) {
+            Map<String, String> contentIdToFileContentMap, PrintWriter writer,
+            String noticeHeader) {
         List<String> fileNameList = new ArrayList();
         fileNameList.addAll(fileNameToContentIdMap.keySet());
         Collections.sort(fileNameList);
 
         writer.println(HTML_HEAD_STRING);
 
+        if (!TextUtils.isEmpty(noticeHeader)) {
+            writer.println(noticeHeader);
+        }
+
         int count = 0;
         Map<String, Integer> contentIdToOrderMap = new HashMap();
         List<ContentIdAndFileNames> contentIdAndFileNamesList = new ArrayList();
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java
index 3930069..78e807c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java
@@ -60,7 +60,7 @@
 
         File cachedHtmlFile = getCachedHtmlFile(mContext);
         if (!isCachedHtmlFileOutdated(xmlFiles, cachedHtmlFile)
-                || generateHtmlFile(xmlFiles, cachedHtmlFile)) {
+                || generateHtmlFile(mContext, xmlFiles, cachedHtmlFile)) {
             return cachedHtmlFile;
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
index 360c19c..ca62485 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.util.Log;
 
+import com.android.settingslib.R;
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
 import java.io.File;
@@ -65,7 +66,7 @@
 
         File cachedHtmlFile = getCachedHtmlFile(mContext);
         if (!isCachedHtmlFileOutdated(xmlFiles, cachedHtmlFile)
-                || generateHtmlFile(xmlFiles, cachedHtmlFile)) {
+                || generateHtmlFile(mContext, xmlFiles, cachedHtmlFile)) {
             return cachedHtmlFile;
         }
 
@@ -101,7 +102,8 @@
         return outdated;
     }
 
-    static boolean generateHtmlFile(List<File> xmlFiles, File htmlFile) {
-        return LicenseHtmlGeneratorFromXml.generateHtml(xmlFiles, htmlFile);
+    static boolean generateHtmlFile(Context context, List<File> xmlFiles, File htmlFile) {
+        return LicenseHtmlGeneratorFromXml.generateHtml(xmlFiles, htmlFile,
+                context.getString(R.string.notice_header));
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
index c3241bb..e9c5238 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
@@ -36,7 +36,13 @@
 
 /**
  * Loader for historical chart data for both network and UID details.
+ *
+ * Deprecated in favor of {@link NetworkCycleChartDataLoader} and
+ * {@link NetworkCycleDataForUidLoader}
+ *
+ * @deprecated
  */
+@Deprecated
 public class ChartDataLoaderCompat extends AsyncTaskLoader<ChartData> {
     private static final String KEY_TEMPLATE = "template";
     private static final String KEY_APP = "app";
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/NetworkCycleChartData.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartData.java
new file mode 100644
index 0000000..9b3ff8b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartData.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Usage data in a billing cycle with bucketized data for plotting the usage chart.
+ */
+public class NetworkCycleChartData extends NetworkCycleData {
+    public static final long BUCKET_DURATION_MS = TimeUnit.DAYS.toMillis(1);
+
+    private List<NetworkCycleData> mUsageBuckets;
+
+    private NetworkCycleChartData() {
+    }
+
+    public List<NetworkCycleData> getUsageBuckets() {
+        return mUsageBuckets;
+    }
+
+    public static class Builder extends NetworkCycleData.Builder {
+        private NetworkCycleChartData mObject = new NetworkCycleChartData();
+
+        public Builder setUsageBuckets(List<NetworkCycleData> buckets) {
+            getObject().mUsageBuckets = buckets;
+            return this;
+        }
+
+        @Override
+        protected NetworkCycleChartData getObject() {
+            return mObject;
+        }
+
+        @Override
+        public NetworkCycleChartData build() {
+            return getObject();
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
new file mode 100644
index 0000000..ec5a0b5
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import android.app.usage.NetworkStats;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Loader for network data usage history. It returns a list of usage data per billing cycle with
+ * bucketized usages.
+ */
+public class NetworkCycleChartDataLoader
+        extends NetworkCycleDataLoader<List<NetworkCycleChartData>> {
+
+    private static final String TAG = "NetworkCycleChartLoader";
+
+    private final List<NetworkCycleChartData> mData;
+
+    private NetworkCycleChartDataLoader(Builder builder) {
+        super(builder);
+        mData = new ArrayList<NetworkCycleChartData>();
+    }
+
+    @Override
+    void recordUsage(long start, long end) {
+        try {
+            final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
+                mNetworkType, mSubId, start, end);
+            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))
+                    .setStartTime(start)
+                    .setEndTime(end)
+                    .setTotalUsage(total);
+                mData.add(builder.build());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception querying network detail.", e);
+        }
+    }
+
+    @Override
+    List<NetworkCycleChartData> getCycleUsage() {
+        return mData;
+    }
+
+    public static Builder<?> builder(Context context) {
+        return new Builder<NetworkCycleChartDataLoader>(context) {
+            @Override
+            public NetworkCycleChartDataLoader build() {
+                return new NetworkCycleChartDataLoader(this);
+            }
+        };
+    }
+
+    private List<NetworkCycleData> getUsageBuckets(long start, long end) {
+        final List<NetworkCycleData> data = new ArrayList<>();
+        long bucketStart = start;
+        long bucketEnd = start + NetworkCycleChartData.BUCKET_DURATION_MS;
+        while (bucketEnd <= end) {
+            long usage = 0L;
+            try {
+                final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
+                    mNetworkType, mSubId, bucketStart, bucketEnd);
+                if (bucket != null) {
+                    usage = bucket.getRxBytes() + bucket.getTxBytes();
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Exception querying network detail.", e);
+            }
+            data.add(new NetworkCycleData.Builder()
+                .setStartTime(bucketStart).setEndTime(bucketEnd).setTotalUsage(usage).build());
+            bucketStart = bucketEnd;
+            bucketEnd += NetworkCycleChartData.BUCKET_DURATION_MS;
+        }
+        return data;
+    }
+
+    public static abstract class Builder<T extends NetworkCycleChartDataLoader>
+            extends NetworkCycleDataLoader.Builder<T> {
+
+        public Builder(Context context) {
+            super(context);
+        }
+
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleData.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleData.java
new file mode 100644
index 0000000..26c65a2
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleData.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+/**
+ * Base data structure representing usage data in a billing cycle.
+ */
+public class NetworkCycleData {
+
+    private long mStartTime;
+    private long mEndTime;
+    private long mTotalUsage;
+
+    protected NetworkCycleData() {
+    }
+
+    public long getStartTime() {
+        return mStartTime;
+    }
+
+    public long getEndTime() {
+        return mEndTime;
+    }
+
+    public long getTotalUsage() {
+        return mTotalUsage;
+    }
+
+    public static class Builder {
+
+        private NetworkCycleData mObject = new NetworkCycleData();
+
+        public Builder setStartTime(long start) {
+            getObject().mStartTime = start;
+            return this;
+        }
+
+        public Builder setEndTime(long end) {
+            getObject().mEndTime = end;
+            return this;
+        }
+
+        public Builder setTotalUsage(long total) {
+            getObject().mTotalUsage = total;
+            return this;
+        }
+
+        protected NetworkCycleData getObject() {
+            return mObject;
+        }
+
+        public NetworkCycleData build() {
+            return getObject();
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUid.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUid.java
new file mode 100644
index 0000000..9d13717
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUid.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 com.android.settingslib.net;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Usage data in a billing cycle for a specific Uid.
+ */
+public class NetworkCycleDataForUid extends NetworkCycleData {
+
+    private long mBackgroudUsage;
+    private long mForegroudUsage;
+
+    private NetworkCycleDataForUid() {
+    }
+
+    public long getBackgroudUsage() {
+        return mBackgroudUsage;
+    }
+
+    public long getForegroudUsage() {
+        return mForegroudUsage;
+    }
+
+    public static class Builder extends NetworkCycleData.Builder {
+
+        private NetworkCycleDataForUid mObject = new NetworkCycleDataForUid();
+
+        public Builder setBackgroundUsage(long backgroundUsage) {
+            getObject().mBackgroudUsage = backgroundUsage;
+            return this;
+        }
+
+        public Builder setForegroundUsage(long foregroundUsage) {
+            getObject().mForegroudUsage = foregroundUsage;
+            return this;
+        }
+
+        @Override
+        public NetworkCycleDataForUid getObject() {
+            return mObject;
+        }
+
+        @Override
+        public NetworkCycleDataForUid build() {
+            return getObject();
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
new file mode 100644
index 0000000..cc970b9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -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.
+ */
+
+package com.android.settingslib.net;
+
+import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND;
+import static android.net.NetworkStats.TAG_NONE;
+
+import android.app.usage.NetworkStats;
+import android.content.Context;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Loader for network data usage history. It returns a list of usage data per billing cycle for a
+ * specific Uid.
+ */
+public class NetworkCycleDataForUidLoader extends
+        NetworkCycleDataLoader<List<NetworkCycleDataForUid>> {
+    private static final String TAG = "NetworkDataForUidLoader";
+
+    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>();
+    }
+
+    @Override
+    void recordUsage(long start, long end) {
+        try {
+            final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid(
+                mNetworkType, mSubId, start, end, mUid);
+            final long total = getTotalUsage(stats);
+            if (total > 0L) {
+                final NetworkCycleDataForUid.Builder builder = new NetworkCycleDataForUid.Builder();
+                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) {
+            Log.e(TAG, "Exception querying network detail.", e);
+        }
+    }
+
+    @Override
+    List<NetworkCycleDataForUid> getCycleUsage() {
+        return mData;
+    }
+
+    public static Builder<?> builder(Context context) {
+        return new Builder<NetworkCycleDataForUidLoader>(context) {
+            @Override
+            public NetworkCycleDataForUidLoader build() {
+                return new NetworkCycleDataForUidLoader(this);
+            }
+        };
+    }
+
+    private long getForegroundUsage(long start, long end) {
+        final NetworkStats stats = mNetworkStatsManager.queryDetailsForUidTagState(
+            mNetworkType, mSubId, start, end, mUid, TAG_NONE, STATE_FOREGROUND);
+        return getTotalUsage(stats);
+    }
+
+    public static abstract class Builder<T extends NetworkCycleDataForUidLoader>
+            extends NetworkCycleDataLoader.Builder<T> {
+
+        private int mUid;
+        private boolean mRetrieveDetail = true;
+
+        public Builder(Context context) {
+            super(context);
+        }
+
+        public Builder<T> setUid(int uid) {
+            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
new file mode 100644
index 0000000..d957801
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
+import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
+
+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;
+import android.net.NetworkPolicyManager;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.format.DateUtils;
+import android.util.Pair;
+
+import com.android.settingslib.NetworkPolicyEditor;
+
+import java.time.ZonedDateTime;
+import java.util.Iterator;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.loader.content.AsyncTaskLoader;
+
+/**
+ * Loader for network data usage history. It returns a list of usage data per billing cycle.
+ */
+public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
+    private static final String TAG = "NetworkCycleDataLoader";
+    protected final NetworkStatsManager mNetworkStatsManager;
+    protected final String mSubId;
+    protected final int mNetworkType;
+    private final NetworkPolicy mPolicy;
+    private final NetworkTemplate mNetworkTemplate;
+    @VisibleForTesting
+    final INetworkStatsService mNetworkStatsService;
+
+    protected NetworkCycleDataLoader(Builder<?> builder) {
+        super(builder.mContext);
+        mSubId = builder.mSubId;
+        mNetworkType = builder.mNetworkType;
+        mNetworkTemplate = builder.mNetworkTemplate;
+        mNetworkStatsManager = (NetworkStatsManager)
+            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
+    protected void onStartLoading() {
+        super.onStartLoading();
+        forceLoad();
+    }
+
+    public D loadInBackground() {
+        if (mPolicy == null) {
+            loadFourWeeksData();
+        } else {
+            loadPolicyData();
+        }
+        return getCycleUsage();
+    }
+
+    @VisibleForTesting
+    void loadPolicyData() {
+        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> iterator =
+            NetworkPolicyManager.cycleIterator(mPolicy);
+        while (iterator.hasNext()) {
+            final Pair<ZonedDateTime, ZonedDateTime> cycle = iterator.next();
+            final long cycleStart = cycle.first.toInstant().toEpochMilli();
+            final long cycleEnd = cycle.second.toInstant().toEpochMilli();
+            recordUsage(cycleStart, cycleEnd);
+        }
+    }
+
+    @Override
+    protected void onStopLoading() {
+        super.onStopLoading();
+        cancelLoad();
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+        cancelLoad();
+    }
+
+    @VisibleForTesting
+    void loadFourWeeksData() {
+        try {
+            final INetworkStatsSession networkSession = mNetworkStatsService.openSession();
+            final NetworkStatsHistory networkHistory = networkSession.getHistoryForNetwork(
+                mNetworkTemplate, FIELD_RX_BYTES | FIELD_TX_BYTES);
+            final long historyStart = networkHistory.getStart();
+            final long historyEnd = networkHistory.getEnd();
+
+            long cycleEnd = historyEnd;
+            while (cycleEnd > historyStart) {
+                final long cycleStart = Math.max(
+                    historyStart, cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4));
+                recordUsage(cycleStart, cycleEnd);
+                cycleEnd = cycleStart;
+            }
+
+            TrafficStats.closeQuietly(networkSession);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @VisibleForTesting
+    abstract void recordUsage(long start, long end);
+
+    abstract D getCycleUsage();
+
+    public static Builder<?> builder(Context context) {
+        return new Builder<NetworkCycleDataLoader>(context) {
+            @Override
+            public NetworkCycleDataLoader build() {
+                return null;
+            }
+        };
+    }
+
+    protected long getTotalUsage(NetworkStats stats) {
+        long bytes = 0L;
+        if (stats != null) {
+            final NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+            while (stats.hasNextBucket() && stats.getNextBucket(bucket)) {
+                bytes += bucket.getRxBytes() + bucket.getTxBytes();
+            }
+            stats.close();
+        }
+        return bytes;
+    }
+
+    public static abstract class Builder<T extends NetworkCycleDataLoader> {
+        private final Context mContext;
+        private String mSubId;
+        private int mNetworkType;
+        private NetworkTemplate mNetworkTemplate;
+
+        public Builder (Context context) {
+            mContext = context;
+        }
+
+        public Builder<T> setSubscriberId(String subId) {
+            mSubId = subId;
+            return this;
+        }
+
+        public Builder<T> setNetworkTemplate(NetworkTemplate template) {
+            mNetworkTemplate = template;
+            mNetworkType = DataUsageController.getNetworkType(template);
+            return this;
+        }
+
+        public abstract T build();
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsDetailLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsDetailLoader.java
deleted file mode 100644
index a070b2a..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsDetailLoader.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.net;
-
-import android.app.usage.NetworkStatsManager;
-import android.app.usage.NetworkStats;
-import android.content.Context;
-import android.os.RemoteException;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-/**
- * Loader for retrieving the network stats details for all UIDs.
- */
-public class NetworkStatsDetailLoader extends AsyncTaskLoader<NetworkStats> {
-
-    private static final String TAG = "NetworkDetailLoader";
-    private final NetworkStatsManager mNetworkStatsManager;
-    private final TelephonyManager mTelephonyManager;
-    private final long mStart;
-    private final long mEnd;
-    private final int mSubId;
-    private final int mNetworkType;
-
-    private NetworkStatsDetailLoader(Builder builder) {
-        super(builder.mContext);
-        mStart = builder.mStart;
-        mEnd = builder.mEnd;
-        mSubId = builder.mSubId;
-        mNetworkType = builder.mNetworkType;
-        mNetworkStatsManager = (NetworkStatsManager)
-                builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
-        mTelephonyManager =
-                (TelephonyManager) builder.mContext.getSystemService(Context.TELEPHONY_SERVICE);
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-        forceLoad();
-    }
-
-    @Override
-    public NetworkStats loadInBackground() {
-        try {
-            return mNetworkStatsManager.queryDetails(
-                    mNetworkType, mTelephonyManager.getSubscriberId(mSubId), mStart, mEnd);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Exception querying network detail.", e);
-            return null;
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        super.onStopLoading();
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-        cancelLoad();
-    }
-
-    public static class Builder {
-        private final Context mContext;
-        private long mStart;
-        private long mEnd;
-        private int mSubId;
-        private int mNetworkType;
-
-        public Builder(Context context) {
-            mContext = context;
-        }
-
-        public Builder setStartTime(long start) {
-            mStart = start;
-            return this;
-        }
-
-        public Builder setEndTime(long end) {
-            mEnd = end;
-            return this;
-        }
-
-        public Builder setSubscriptionId(int subId) {
-            mSubId = subId;
-            return this;
-        }
-
-        public Builder setNetworkType(int networkType) {
-            mNetworkType = networkType;
-            return this;
-        }
-
-        public NetworkStatsDetailLoader build() {
-            return new NetworkStatsDetailLoader(this);
-        }
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
new file mode 100644
index 0000000..34e6097
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
@@ -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.
+ */
+
+package com.android.settingslib.net;
+
+import android.app.usage.NetworkStatsManager;
+import android.app.usage.NetworkStats;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.loader.content.AsyncTaskLoader;
+
+/**
+ * Loader for retrieving the network stats summary for all UIDs.
+ */
+public class NetworkStatsSummaryLoader extends AsyncTaskLoader<NetworkStats> {
+
+    private static final String TAG = "NetworkDetailLoader";
+    private final NetworkStatsManager mNetworkStatsManager;
+    private final long mStart;
+    private final long mEnd;
+    private final String mSubId;
+    private final int mNetworkType;
+
+    private NetworkStatsSummaryLoader(Builder builder) {
+        super(builder.mContext);
+        mStart = builder.mStart;
+        mEnd = builder.mEnd;
+        mSubId = builder.mSubId;
+        mNetworkType = builder.mNetworkType;
+        mNetworkStatsManager = (NetworkStatsManager)
+                builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
+    }
+
+    @Override
+    protected void onStartLoading() {
+        super.onStartLoading();
+        forceLoad();
+    }
+
+    @Override
+    public NetworkStats loadInBackground() {
+        try {
+            return mNetworkStatsManager.querySummary(mNetworkType, mSubId, mStart, mEnd);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception querying network detail.", e);
+            return null;
+        }
+    }
+
+    @Override
+    protected void onStopLoading() {
+        super.onStopLoading();
+        cancelLoad();
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+        cancelLoad();
+    }
+
+    public static class Builder {
+        private final Context mContext;
+        private long mStart;
+        private long mEnd;
+        private String mSubId;
+        private int mNetworkType;
+
+        public Builder(Context context) {
+            mContext = context;
+        }
+
+        public Builder setStartTime(long start) {
+            mStart = start;
+            return this;
+        }
+
+        public Builder setEndTime(long end) {
+            mEnd = end;
+            return this;
+        }
+
+        public Builder setSubscriberId(String subId) {
+            mSubId = subId;
+            return this;
+        }
+
+        public Builder setNetworkType(int networkType) {
+            mNetworkType = networkType;
+            return this;
+        }
+
+        public NetworkStatsSummaryLoader build() {
+            return new NetworkStatsSummaryLoader(this);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index fe0b35b..089f773 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -163,6 +163,12 @@
                 ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
     }
 
+    /** Refresh the status label on Locale changed. */
+    public void refreshLocale() {
+        updateStatusLabel();
+        mCallback.run();
+    }
+
     private String getValidSsid(WifiInfo info) {
         String ssid = info.getSSID();
         if (ssid != null && !WifiSsid.NONE.equals(ssid)) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 9050b4b..0dbc037 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -81,7 +81,7 @@
     private static final long DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS = 20 * DateUtils.MINUTE_IN_MILLIS;
 
     /** Maximum age of scan results to hold onto while actively scanning. **/
-    private static final long MAX_SCAN_RESULT_AGE_MILLIS = 25000;
+    private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000;
 
     private static final String TAG = "WifiTracker";
     private static final boolean DBG() {
@@ -134,8 +134,8 @@
     /**
      * Tracks whether fresh scan results have been received since scanning start.
      *
-     * <p>If this variable is false, we will not evict the scan result cache or invoke callbacks
-     * so that we do not update the UI with stale data / clear out existing UI elements prematurely.
+     * <p>If this variable is false, we will not invoke callbacks so that we do not
+     * update the UI with stale data / clear out existing UI elements prematurely.
      */
     private boolean mStaleScanResults = true;
 
@@ -327,7 +327,8 @@
      * <p>Intended to only be invoked within {@link #onStart()}.
      */
     @MainThread
-    private void forceUpdate() {
+    @VisibleForTesting
+    void forceUpdate() {
         mLastInfo = mWifiManager.getConnectionInfo();
         mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
 
@@ -443,10 +444,8 @@
             mScanResultCache.put(newResult.BSSID, newResult);
         }
 
-        // Don't evict old results if no new scan results
-        if (!mStaleScanResults) {
-            evictOldScans();
-        }
+        // Evict old results in all conditions
+        evictOldScans();
 
         ArrayMap<String, List<ScanResult>> scanResultsByApKey = new ArrayMap<>();
         for (ScanResult result : mScanResultCache.values()) {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 517db78..1860b31 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
@@ -104,6 +103,10 @@
     private static final byte SCORE_2 = 15;
     private static final int BADGE_2 = AccessPoint.Speed.FAST;
 
+    private static final String SSID_3 = "ssid3";
+    private static final String BSSID_3 = "CC:00:00:00:00:00";
+    private static final int RSSI_3 = -40;
+
     // TODO(b/65594609): Convert mutable Data objects to instance variables / builder pattern
     private static final int NETWORK_ID_1 = 123;
     private static final int CONNECTED_RSSI = -50;
@@ -255,6 +258,19 @@
                 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
     }
 
+    private static ScanResult buildStaleScanResult() {
+        return new ScanResult(
+                WifiSsid.createFromAsciiEncoded(SSID_3),
+                BSSID_3,
+                0, // hessid
+                0, //anqpDomainId
+                null, // osuProviders
+                "", // capabilities
+                RSSI_3,
+                0, // frequency
+                0 /* microsecond timestamp */);
+    }
+
     private WifiTracker createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(
                     Intent ... intents)
             throws InterruptedException {
@@ -896,4 +912,18 @@
         assertThat(aps.get(0).isReachable()).isTrue();
         assertThat(aps.get(1).isReachable()).isTrue();
     }
+
+    @Test
+    public void onStart_updateScanResults_evictOldScanResult() {
+        when(mockWifiManager.getScanResults()).thenReturn(
+                Arrays.asList(buildScanResult1(), buildScanResult2(), buildStaleScanResult()));
+        WifiTracker tracker = createMockedWifiTracker();
+
+        tracker.forceUpdate();
+
+        // Only has scanResult1 and scanResult2
+        assertThat(tracker.getAccessPoints()).hasSize(2);
+        assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1);
+        assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
index 0ca2e87..ede248b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
@@ -52,6 +52,7 @@
                 @Override
                 public List<ResourcePath> getIncludedResourcePaths() {
                     final List<ResourcePath> paths = super.getIncludedResourcePaths();
+                    paths.add(resourcePath("file:frameworks/base/packages/SettingsLib/AppPreference/res"));
                     paths.add(resourcePath("file:frameworks/base/packages/SettingsLib/HelpUtils/res"));
                     paths.add(resourcePath("file:frameworks/base/packages/SettingsLib/RestrictedLockUtils/res"));
                     paths.add(resourcePath("file:frameworks/base/packages/SettingsLib/res"));
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 7baded8..62b5688 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -118,7 +118,7 @@
      * Test to verify addDevice().
      */
     @Test
-    public void testAddDevice_validCachedDevices_devicesAdded() {
+    public void addDevice_validCachedDevices_devicesAdded() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -136,7 +136,7 @@
      * Test to verify getName().
      */
     @Test
-    public void testGetName_validCachedDevice_nameFound() {
+    public void getName_validCachedDevice_nameFound() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         assertThat(mCachedDeviceManager.getName(mDevice1)).isEqualTo(DEVICE_ALIAS_1);
@@ -146,7 +146,7 @@
      * Test to verify onDeviceNameUpdated().
      */
     @Test
-    public void testOnDeviceNameUpdated_validName_nameUpdated() {
+    public void onDeviceNameUpdated_validName_nameUpdated() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1);
@@ -161,7 +161,7 @@
      * Test to verify clearNonBondedDevices().
      */
     @Test
-    public void testClearNonBondedDevices_bondedAndNonBondedDevices_nonBondedDevicesCleared() {
+    public void clearNonBondedDevices_bondedAndNonBondedDevices_nonBondedDevicesCleared() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -193,7 +193,7 @@
      * Test to verify clearNonBondedDevices() for hearing aids.
      */
     @Test
-    public void testClearNonBondedDevices_HearingAids_nonBondedHAsClearedFromCachedDevicesMap() {
+    public void clearNonBondedDevices_HearingAids_nonBondedHAsClearedFromCachedDevicesMap() {
         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
 
@@ -214,7 +214,7 @@
      * Test to verify onHiSyncIdChanged() for hearing aid devices with same HiSyncId.
      */
     @Test
-    public void testOnHiSyncIdChanged_sameHiSyncId_populateInDifferentLists() {
+    public void onHiSyncIdChanged_sameHiSyncId_populateInDifferentLists() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -247,7 +247,7 @@
      * device is connected and other is disconnected. The connected device should be chosen.
      */
     @Test
-    public void testOnHiSyncIdChanged_sameHiSyncIdAndOneConnected_chooseConnectedDevice() {
+    public void onHiSyncIdChanged_sameHiSyncIdAndOneConnected_chooseConnectedDevice() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -282,7 +282,7 @@
      * Test to verify onHiSyncIdChanged() for hearing aid devices with different HiSyncId.
      */
     @Test
-    public void testOnHiSyncIdChanged_differentHiSyncId_populateInSameList() {
+    public void onHiSyncIdChanged_differentHiSyncId_populateInSameList() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -316,7 +316,7 @@
      * Test to verify onProfileConnectionStateChanged() for single hearing aid device connection.
      */
     @Test
-    public void testOnProfileConnectionStateChanged_singleDeviceConnected_visible() {
+    public void onProfileConnectionStateChanged_singleDeviceConnected_visible() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
@@ -353,7 +353,7 @@
      * devices are disconnected and they get connected.
      */
     @Test
-    public void testOnProfileConnectionStateChanged_twoDevicesConnected_oneDeviceVisible() {
+    public void onProfileConnectionStateChanged_twoDevicesConnected_oneDeviceVisible() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -405,7 +405,7 @@
      * devices are connected and they get disconnected.
      */
     @Test
-    public void testOnProfileConnectionStateChanged_twoDevicesDisconnected_oneDeviceVisible() {
+    public void onProfileConnectionStateChanged_twoDevicesDisconnected_oneDeviceVisible() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -458,7 +458,7 @@
      * Test to verify OnDeviceUnpaired() for a paired hearing Aid device pair.
      */
     @Test
-    public void testOnDeviceUnpaired_bothHearingAidsPaired_removesItsPairFromList() {
+    public void onDeviceUnpaired_bothHearingAidsPaired_removesItsPairFromList() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -488,7 +488,7 @@
      * Test to verify OnDeviceUnpaired() for paired hearing Aid devices which are not a pair.
      */
     @Test
-    public void testOnDeviceUnpaired_bothHearingAidsNotPaired_doesNotRemoveAnyDeviceFromList() {
+    public void onDeviceUnpaired_bothHearingAidsNotPaired_doesNotRemoveAnyDeviceFromList() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -532,7 +532,7 @@
      * Test to verify addDevice() for hearing aid devices with same HiSyncId.
      */
     @Test
-    public void testAddDevice_hearingAidDevicesWithSameHiSyncId_populateInDifferentLists() {
+    public void addDevice_hearingAidDevicesWithSameHiSyncId_populateInDifferentLists() {
         doAnswer((invocation) -> mHearingAidProfile).when(mLocalProfileManager)
             .getHearingAidProfile();
         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
@@ -560,7 +560,7 @@
      * Test to verify addDevice() for hearing aid devices with different HiSyncId.
      */
     @Test
-    public void testAddDevice_hearingAidDevicesWithDifferentHiSyncId_populateInSameList() {
+    public void addDevice_hearingAidDevicesWithDifferentHiSyncId_populateInSameList() {
         doAnswer((invocation) -> mHearingAidProfile).when(mLocalProfileManager)
             .getHearingAidProfile();
         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
@@ -592,7 +592,7 @@
      * Test to verify getHearingAidPairDeviceSummary() for hearing aid devices with same HiSyncId.
      */
     @Test
-    public void testGetHearingAidPairDeviceSummary_bothHearingAidsPaired_returnsSummaryOfPair() {
+    public void getHearingAidPairDeviceSummary_bothHearingAidsPaired_returnsSummaryOfPair() {
         mCachedDevice1.setHiSyncId(HISYNCID1);
         mCachedDevice2.setHiSyncId(HISYNCID1);
         mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
@@ -609,7 +609,7 @@
      * HiSyncId.
      */
     @Test
-    public void testGetHearingAidPairDeviceSummary_bothHearingAidsNotPaired_returnsNull() {
+    public void getHearingAidPairDeviceSummary_bothHearingAidsNotPaired_returnsNull() {
         mCachedDevice1.setHiSyncId(HISYNCID1);
         mCachedDevice2.setHiSyncId(HISYNCID2);
         mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
@@ -625,7 +625,7 @@
      * Test to verify updateHearingAidsDevices().
      */
     @Test
-    public void testUpdateHearingAidDevices_hiSyncIdAvailable_setsHiSyncId() {
+    public void updateHearingAidDevices_hiSyncIdAvailable_setsHiSyncId() {
         doAnswer((invocation) -> mHearingAidProfile).when(mLocalProfileManager)
             .getHearingAidProfile();
         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
@@ -643,7 +643,7 @@
      * Test to verify onBtClassChanged().
      */
     @Test
-    public void testOnBtClassChanged_validBtClass_classChanged() {
+    public void onBtClassChanged_validBtClass_classChanged() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         assertThat(cachedDevice1.getBtClass()).isEqualTo(DEVICE_CLASS_1);
@@ -658,7 +658,7 @@
      * Test to verify onDeviceDisappeared().
      */
     @Test
-    public void testOnDeviceDisappeared_deviceBondedUnbonded_unbondedDeviceDisappeared() {
+    public void onDeviceDisappeared_deviceBondedUnbonded_unbondedDeviceDisappeared() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
 
@@ -673,7 +673,7 @@
      * Test to verify onActiveDeviceChanged().
      */
     @Test
-    public void testOnActiveDeviceChanged_connectedDevices_activeDeviceChanged() {
+    public void onActiveDeviceChanged_connectedDevices_activeDeviceChanged() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -736,7 +736,7 @@
      * Test to verify onActiveDeviceChanged() with A2DP and Hearing Aid.
      */
     @Test
-    public void testOnActiveDeviceChanged_withA2dpAndHearingAid() {
+    public void onActiveDeviceChanged_withA2dpAndHearingAid() {
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         assertThat(cachedDevice1).isNotNull();
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index c18db11..f6201dd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -79,74 +80,74 @@
     }
 
     @Test
-    public void testGetConnectionSummary_testSingleProfileConnectDisconnect() {
+    public void getConnectionSummary_testSingleProfileConnectDisconnect() {
         // Test without battery level
         // Set PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set PAN profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Test with battery level
         mBatteryLevel = 10;
         // Set PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery");
 
         // Set PAN profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
 
         // Set PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set PAN profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
     }
 
     @Test
-    public void testGetConnectionSummary_testMultipleProfileConnectDisconnect() {
+    public void getConnectionSummary_testMultipleProfileConnectDisconnect() {
         mBatteryLevel = 10;
 
         // Set HFP, A2DP and PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery");
 
         // Disconnect HFP only and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "10% battery");
 
         // Disconnect A2DP only and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "10% battery");
 
         // Disconnect both HFP and A2DP and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "10% battery");
 
         // Disconnect all profiles and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
     }
 
     @Test
-    public void testGetConnectionSummary_testSingleProfileActiveDeviceA2dp() {
+    public void getConnectionSummary_testSingleProfileActiveDeviceA2dp() {
         // Test without battery level
         // Set A2DP profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for A2DP and test connection state summary
@@ -159,26 +160,26 @@
                 "Active, 10% battery");
 
         // Set A2DP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set A2DP profile to be connected, Active and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set A2DP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
     }
 
     @Test
-    public void testGetConnectionSummary_testSingleProfileActiveDeviceHfp() {
+    public void getConnectionSummary_testSingleProfileActiveDeviceHfp() {
         // Test without battery level
         // Set HFP profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for HFP and test connection state summary
@@ -193,26 +194,26 @@
                 "Active, 10% battery");
 
         // Set HFP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set HFP profile to be connected, Active and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set HFP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
     }
 
     @Test
-    public void testGetConnectionSummary_testSingleProfileActiveDeviceHearingAid() {
+    public void getConnectionSummary_testSingleProfileActiveDeviceHearingAid() {
         // Test without battery level
         // Set Hearing Aid profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for Hearing Aid and test connection state summary
@@ -227,11 +228,11 @@
     }
 
     @Test
-    public void testGetConnectionSummary_testMultipleProfilesActiveDevice() {
+    public void getConnectionSummary_testMultipleProfilesActiveDevice() {
         // Test without battery level
         // Set A2DP and HFP profiles to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for A2DP and HFP and test connection state summary
@@ -246,14 +247,14 @@
 
         // Disconnect A2DP only and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "10% battery");
 
         // Disconnect HFP only and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "Active, 10% battery");
@@ -261,15 +262,15 @@
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set A2DP and HFP profiles to be connected, Active and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set A2DP and HFP profiles to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
     }
 
@@ -277,32 +278,32 @@
     public void getCarConnectionSummary_singleProfileConnectDisconnect() {
         // Test without battery level
         // Set PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
 
         // Set PAN profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
 
         // Test with battery level
         mBatteryLevel = 10;
         // Set PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, battery 10%");
 
         // Set PAN profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
 
         // Set PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
 
         // Set PAN profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
     }
 
@@ -311,29 +312,29 @@
         mBatteryLevel = 10;
 
         // Set HFP, A2DP and PAN profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, battery 10%");
 
         // Disconnect HFP only and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
                 "Connected (no phone), battery 10%");
 
         // Disconnect A2DP only and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
                 "Connected (no media), battery 10%");
 
         // Disconnect both HFP and A2DP and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
                 "Connected (no phone or media), battery 10%");
 
         // Disconnect all profiles and test connection state summary
-        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
     }
 
@@ -341,7 +342,7 @@
     public void getCarConnectionSummary_singleProfileActiveDeviceA2dp() {
         // Test without battery level
         // Set A2DP profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for A2DP and test connection state summary
@@ -354,18 +355,18 @@
                 "Connected, battery 10%, active (media)");
 
         // Set A2DP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set A2DP profile to be connected, Active and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active (media)");
 
         // Set A2DP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
     }
 
@@ -373,7 +374,7 @@
     public void getCarConnectionSummary_singleProfileActiveDeviceHfp() {
         // Test without battery level
         // Set HFP profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for HFP and test connection state summary
@@ -386,18 +387,18 @@
                 "Connected, battery 10%, active (phone)");
 
         // Set HFP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set HFP profile to be connected, Active and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active (phone)");
 
         // Set HFP profile to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
     }
 
@@ -405,7 +406,7 @@
     public void getCarConnectionSummary_singleProfileActiveDeviceHearingAid() {
         // Test without battery level
         // Set Hearing Aid profile to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for Hearing Aid and test connection state summary
@@ -414,8 +415,7 @@
 
         // Set Hearing Aid profile to be disconnected and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID);
-        mCachedDevice.onProfileStateChanged(mHearingAidProfile,
-                BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
     }
 
@@ -423,8 +423,8 @@
     public void getCarConnectionSummary_multipleProfilesActiveDevice() {
         // Test without battery level
         // Set A2DP and HFP profiles to be connected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for A2DP and HFP and test connection state summary
@@ -439,14 +439,14 @@
 
         // Disconnect A2DP only and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
                 "Connected (no media), battery 10%, active (phone)");
 
         // Disconnect HFP only and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
                 "Connected (no phone), battery 10%, active (media)");
@@ -454,21 +454,21 @@
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set A2DP and HFP profiles to be connected, Active and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active");
 
         // Set A2DP and HFP profiles to be disconnected and test connection state summary
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
     }
 
 
     @Test
-    public void testDeviceName_testAliasNameAvailable() {
+    public void deviceName_testAliasNameAvailable() {
         when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);
         when(mDevice.getName()).thenReturn(DEVICE_NAME);
         CachedBluetoothDevice cachedBluetoothDevice =
@@ -480,7 +480,7 @@
     }
 
     @Test
-    public void testDeviceName_testNameNotAvailable() {
+    public void deviceName_testNameNotAvailable() {
         CachedBluetoothDevice cachedBluetoothDevice =
                 new CachedBluetoothDevice(mContext, mProfileManager, mDevice);
         // Verify device address is returned on getName
@@ -490,7 +490,7 @@
     }
 
     @Test
-    public void testDeviceName_testRenameDevice() {
+    public void deviceName_testRenameDevice() {
         final String[] alias = {DEVICE_ALIAS};
         doAnswer(invocation -> alias[0]).when(mDevice).getAliasName();
         doAnswer(invocation -> {
@@ -513,7 +513,7 @@
     }
 
     @Test
-    public void testSetActive() {
+    public void setActive() {
         when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
         when(mProfileManager.getHeadsetProfile()).thenReturn(mHfpProfile);
         when(mA2dpProfile.setActiveDevice(any(BluetoothDevice.class))).thenReturn(true);
@@ -521,19 +521,19 @@
 
         assertThat(mCachedDevice.setActive()).isFalse();
 
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.setActive()).isTrue();
 
-        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         assertThat(mCachedDevice.setActive()).isTrue();
 
-        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.setActive()).isFalse();
     }
 
     @Test
-    public void testIsA2dpDevice_isA2dpDevice() {
+    public void isA2dpDevice_isA2dpDevice() {
         when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
         when(mA2dpProfile.getConnectionStatus(mDevice)).
                 thenReturn(BluetoothProfile.STATE_CONNECTED);
@@ -542,7 +542,7 @@
     }
 
     @Test
-    public void testIsA2dpDevice_isNotA2dpDevice() {
+    public void isA2dpDevice_isNotA2dpDevice() {
         when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
         when(mA2dpProfile.getConnectionStatus(mDevice)).
                 thenReturn(BluetoothProfile.STATE_DISCONNECTING);
@@ -551,7 +551,7 @@
     }
 
     @Test
-    public void testIsHfpDevice_isHfpDevice() {
+    public void isHfpDevice_isHfpDevice() {
         when(mProfileManager.getHeadsetProfile()).thenReturn(mHfpProfile);
         when(mHfpProfile.getConnectionStatus(mDevice)).
                 thenReturn(BluetoothProfile.STATE_CONNECTED);
@@ -637,4 +637,24 @@
 
         verify(mDevice, never()).setAlias(any());
     }
+
+    @Test
+    public void getProfileConnectionState_nullProfile_returnDisconnected() {
+        assertThat(mCachedDevice.getProfileConnectionState(null)).isEqualTo(
+                BluetoothProfile.STATE_DISCONNECTED);
+    }
+
+    @Test
+    public void getProfileConnectionState_profileConnected_returnConnected() {
+        doReturn(BluetoothProfile.STATE_CONNECTED).when(mA2dpProfile).getConnectionStatus(
+                any(BluetoothDevice.class));
+
+        assertThat(mCachedDevice.getProfileConnectionState(mA2dpProfile)).isEqualTo(
+                BluetoothProfile.STATE_CONNECTED);
+    }
+
+    private void updateProfileStatus(LocalBluetoothProfile profile, int status) {
+        doReturn(status).when(profile).getConnectionStatus(mDevice);
+        mCachedDevice.onProfileStateChanged(profile, status);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PbapClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PbapClientProfileTest.java
new file mode 100644
index 0000000..e4a444c
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PbapClientProfileTest.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.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothPbapClient;
+import android.bluetooth.BluetoothProfile;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
+public class PbapClientProfileTest {
+
+    @Mock
+    private CachedBluetoothDeviceManager mDeviceManager;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private BluetoothPbapClient mService;
+    @Mock
+    private CachedBluetoothDevice mCachedBluetoothDevice;
+    @Mock
+    private BluetoothDevice mBluetoothDevice;
+    private BluetoothProfile.ServiceListener mServiceListener;
+    private PbapClientProfile mProfile;
+    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+        mProfile = new PbapClientProfile(RuntimeEnvironment.application,
+                mDeviceManager, mProfileManager);
+        mServiceListener = mShadowBluetoothAdapter.getServiceListener();
+        mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, mService);
+    }
+
+    @Test
+    public void connect_shouldConnectBluetoothPbapClient() {
+        mProfile.connect(mBluetoothDevice);
+        verify(mService).connect(mBluetoothDevice);
+    }
+
+    @Test
+    public void disconnect_shouldDisconnectBluetoothPbapClient() {
+        mProfile.disconnect(mBluetoothDevice);
+        verify(mService).disconnect(mBluetoothDevice);
+    }
+
+    @Test
+    public void getConnectionStatus_shouldReturnConnectionState() {
+        when(mService.getConnectionState(mBluetoothDevice)).
+                thenReturn(BluetoothProfile.STATE_CONNECTED);
+        assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
+                isEqualTo(BluetoothProfile.STATE_CONNECTED);
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/SapProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/SapProfileTest.java
new file mode 100644
index 0000000..9bb53ee
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/SapProfileTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSap;
+import android.bluetooth.BluetoothProfile;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
+public class SapProfileTest {
+
+    @Mock
+    private CachedBluetoothDeviceManager mDeviceManager;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private BluetoothSap mService;
+    @Mock
+    private CachedBluetoothDevice mCachedBluetoothDevice;
+    @Mock
+    private BluetoothDevice mBluetoothDevice;
+    private BluetoothProfile.ServiceListener mServiceListener;
+    private SapProfile mProfile;
+    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+        mProfile = new SapProfile(RuntimeEnvironment.application, mDeviceManager, mProfileManager);
+        mServiceListener = mShadowBluetoothAdapter.getServiceListener();
+        mServiceListener.onServiceConnected(BluetoothProfile.SAP, mService);
+    }
+
+    @Test
+    public void connect_shouldConnectBluetoothSap() {
+        mProfile.connect(mBluetoothDevice);
+        verify(mService).connect(mBluetoothDevice);
+    }
+
+    @Test
+    public void disconnect_shouldDisconnectBluetoothSap() {
+        mProfile.disconnect(mBluetoothDevice);
+        verify(mService).disconnect(mBluetoothDevice);
+    }
+
+    @Test
+    public void getConnectionStatus_shouldReturnConnectionState() {
+        when(mService.getConnectionState(mBluetoothDevice)).
+                thenReturn(BluetoothProfile.STATE_CONNECTED);
+        assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
+                isEqualTo(BluetoothProfile.STATE_CONNECTED);
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
index c23ad79..887c1d5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
@@ -38,13 +38,13 @@
 import com.android.settingslib.core.lifecycle.events.OnResume;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
-import com.android.settingslib.testutils.FragmentTestUtils;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
 import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class LifecycleTest {
@@ -184,7 +184,7 @@
     @Test
     public void runThroughDialogFragmentLifecycles_shouldObserveEverything() {
         final TestDialogFragment fragment = new TestDialogFragment();
-        FragmentTestUtils.startFragment(fragment);
+        FragmentController.setupFragment(fragment);
 
         fragment.onCreateOptionsMenu(null, null);
         fragment.onPrepareOptionsMenu(null);
@@ -208,7 +208,7 @@
     @Test
     public void runThroughFragmentLifecycles_shouldObserveEverything() {
         final TestFragment fragment = new TestFragment();
-        FragmentTestUtils.startFragment(fragment);
+        FragmentController.setupFragment(fragment);
 
         fragment.onCreateOptionsMenu(null, null);
         fragment.onPrepareOptionsMenu(null);
@@ -248,7 +248,7 @@
     @Test
     public void onOptionItemSelectedShortCircuitsIfAnObserverHandlesTheMenuItem() {
         final TestFragment fragment = new TestFragment();
-        FragmentTestUtils.startFragment(fragment);
+        FragmentController.setupFragment(fragment);
 
         final OptionItemAccepter accepter = new OptionItemAccepter();
         fragment.getLifecycle().addObserver(accepter);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
index 96b2a14..b00476b2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
@@ -50,7 +50,7 @@
             + "<file-content contentId=\"0\"><![CDATA[license content #0]]></file-content>\n"
             + "</licenses2>";
 
-    private static final String EXPECTED_HTML_STRING =
+    private static final String HTML_HEAD_STRING =
             "<html><head>\n"
             + "<style type=\"text/css\">\n"
             + "body { padding: 0; font-family: sans-serif; }\n"
@@ -63,8 +63,12 @@
             + "</head>"
             + "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n"
             + "<div class=\"toc\">\n"
-            + "<ul>\n"
-            + "<li><a href=\"#id0\">/file0</a></li>\n"
+            + "<ul>\n";
+
+    private static final String HTML_CUSTOM_HEADING = "Custom heading";
+
+    private static final String HTML_BODY_STRING =
+            "<li><a href=\"#id0\">/file0</a></li>\n"
             + "<li><a href=\"#id0\">/file1</a></li>\n"
             + "</ul>\n"
             + "</div><!-- table of contents -->\n"
@@ -81,6 +85,11 @@
             + "</td></tr><!-- same-license -->\n"
             + "</table></body></html>\n";
 
+    private static final String EXPECTED_HTML_STRING = HTML_HEAD_STRING + HTML_BODY_STRING;
+
+    private static final String EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING =
+            HTML_HEAD_STRING + HTML_CUSTOM_HEADING + "\n" + HTML_BODY_STRING;
+
     @Test
     public void testParseValidXmlStream() throws XmlPullParserException, IOException {
         Map<String, String> fileNameToContentIdMap = new HashMap<String, String>();
@@ -117,7 +126,23 @@
 
         StringWriter output = new StringWriter();
         LicenseHtmlGeneratorFromXml.generateHtml(
-                fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output));
+                fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output), "");
         assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING);
     }
+
+    @Test
+    public void testGenerateHtmlWithCustomHeading() {
+        Map<String, String> fileNameToContentIdMap = new HashMap<String, String>();
+        Map<String, String> contentIdToFileContentMap = new HashMap<String, String>();
+
+        fileNameToContentIdMap.put("/file0", "0");
+        fileNameToContentIdMap.put("/file1", "0");
+        contentIdToFileContentMap.put("0", "license content #0");
+
+        StringWriter output = new StringWriter();
+        LicenseHtmlGeneratorFromXml.generateHtml(
+                fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output),
+                HTML_CUSTOM_HEADING);
+        assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderCompatTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderCompatTest.java
index 12a4e69..c32cc99 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderCompatTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlLoaderCompatTest.java
@@ -142,7 +142,7 @@
         }
 
         @Implementation
-        static boolean generateHtmlFile(List<File> xmlFiles, File htmlFile) {
+        static boolean generateHtmlFile(Context context, List<File> xmlFiles, File htmlFile) {
             return sGenerateHtmlFileSucceeded;
         }
     }
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
new file mode 100644
index 0000000..0a03631
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import static 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.os.RemoteException;
+import android.text.format.DateUtils;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class NetworkCycleChartDataLoaderTest {
+
+    @Mock
+    private NetworkStatsManager mNetworkStatsManager;
+    @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
+    private Context mContext;
+
+    private NetworkCycleChartDataLoader mLoader;
+
+    @Before
+    public void setUp() {
+        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_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)
+            .setSubscriberId(subId).build();
+
+        mLoader.recordUsage(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
new file mode 100644
index 0000000..2314f27
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import static 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;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class NetworkCycleDataForUidLoaderTest {
+
+    @Mock
+    private NetworkStatsManager mNetworkStatsManager;
+    @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
+    private Context mContext;
+
+    private NetworkCycleDataForUidLoader mLoader;
+
+    @Before
+    public void setUp() {
+        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_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 = 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
new file mode 100644
index 0000000..9d60a97
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.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.settingslib.net;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.nullable;
+import static org.mockito.Mockito.doNothing;
+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.NetworkStatsManager;
+import android.content.Context;
+import android.net.ConnectivityManager;
+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;
+import android.text.format.DateUtils;
+import android.util.Range;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.time.ZonedDateTime;
+import java.util.Iterator;
+import java.util.List;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class NetworkCycleDataLoaderTest {
+
+    @Mock
+    private NetworkStatsManager mNetworkStatsManager;
+    @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
+    private Context mContext;
+    @Mock
+    private NetworkPolicy mPolicy;
+    @Mock
+    private Iterator<Range<ZonedDateTime>> mIterator;
+    @Mock
+    private INetworkStatsService mNetworkStatsService;
+
+    private NetworkCycleDataTestLoader mLoader;
+
+    @Before
+    public void setUp() {
+        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
+    public void loadInBackground_noNetworkPolicy_shouldLoad4WeeksData() {
+        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
+        doNothing().when(mLoader).loadFourWeeksData();
+
+        mLoader.loadInBackground();
+
+        verify(mLoader).loadFourWeeksData();
+    }
+
+    @Test
+    public void loadInBackground_hasNetworkPolicy_shouldLoadPolicyData() {
+        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
+        ReflectionHelpers.setField(mLoader, "mPolicy", mPolicy);
+
+        mLoader.loadInBackground();
+
+        verify(mLoader).loadPolicyData();
+    }
+
+    @Test
+    public void loadPolicyData_shouldRecordUsageFromPolicyCycle() {
+        final int networkType = ConnectivityManager.TYPE_MOBILE;
+        final String subId = "TestSubscriber";
+        final ZonedDateTime now = ZonedDateTime.now();
+        final Range<ZonedDateTime> cycle = new Range<>(now, now);
+        final long nowInMs = now.toInstant().toEpochMilli();
+        // mock 1 cycle data.
+        // hasNext() will be called internally in next(), hence setting it to return true twice.
+        when(mIterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(mIterator.next()).thenReturn(cycle);
+        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
+        ReflectionHelpers.setField(mLoader, "mPolicy", mPolicy);
+        ReflectionHelpers.setField(mLoader, "mNetworkType", networkType);
+        ReflectionHelpers.setField(mLoader, "mSubId", subId);
+
+        mLoader.loadPolicyData();
+
+        verify(mLoader).recordUsage(nowInMs, nowInMs);
+    }
+
+    @Test
+    public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() throws RemoteException {
+        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
+        ReflectionHelpers.setField(mLoader, "mNetworkStatsService", mNetworkStatsService);
+        final INetworkStatsSession networkSession = mock(INetworkStatsSession.class);
+        when(mNetworkStatsService.openSession()).thenReturn(networkSession);
+        final NetworkStatsHistory networkHistory = mock(NetworkStatsHistory.class);
+        when(networkSession.getHistoryForNetwork(nullable(NetworkTemplate.class), anyInt()))
+            .thenReturn(networkHistory);
+        final long now = System.currentTimeMillis();
+        final long fourWeeksAgo = now - (DateUtils.WEEK_IN_MILLIS * 4);
+        when(networkHistory.getStart()).thenReturn(fourWeeksAgo);
+        when(networkHistory.getEnd()).thenReturn(now);
+
+        mLoader.loadFourWeeksData();
+
+        verify(mLoader).recordUsage(fourWeeksAgo, now);
+    }
+
+    public class NetworkCycleDataTestLoader extends NetworkCycleDataLoader<List<NetworkCycleData>> {
+
+        private NetworkCycleDataTestLoader(Context context) {
+            super(NetworkCycleDataLoader.builder(mContext));
+            mContext = context;
+        }
+
+        @Override
+        void recordUsage(long start, long end) {
+        }
+
+        @Override
+        List<NetworkCycleData> getCycleUsage() {
+            return null;
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/FragmentTestUtils.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/FragmentTestUtils.java
deleted file mode 100644
index d8e73b7..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/FragmentTestUtils.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.testutils;
-
-import android.os.Bundle;
-import android.widget.LinearLayout;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentManager;
-
-import org.robolectric.Robolectric;
-
-/**
- * Utilities for creating Fragments for testing.
- * <p>
- * TODO(b/111195449) - Duplicated from org.robolectric.shadows.support.v4.SupportFragmentTestUtil
- */
-@Deprecated
-public class FragmentTestUtils {
-
-    public static void startFragment(Fragment fragment) {
-        buildFragmentManager(FragmentUtilActivity.class)
-                .beginTransaction().add(fragment, null).commit();
-    }
-
-    public static void startFragment(Fragment fragment,
-            Class<? extends FragmentActivity> activityClass) {
-        buildFragmentManager(activityClass)
-                .beginTransaction().add(fragment, null).commit();
-    }
-
-    public static void startVisibleFragment(Fragment fragment) {
-        buildFragmentManager(FragmentUtilActivity.class)
-                .beginTransaction().add(1, fragment, null).commit();
-    }
-
-    public static void startVisibleFragment(Fragment fragment,
-            Class<? extends FragmentActivity> activityClass, int containerViewId) {
-        buildFragmentManager(activityClass)
-                .beginTransaction().add(containerViewId, fragment, null).commit();
-    }
-
-    private static FragmentManager buildFragmentManager(
-            Class<? extends FragmentActivity> activityClass) {
-        FragmentActivity activity = Robolectric.setupActivity(activityClass);
-        return activity.getSupportFragmentManager();
-    }
-
-    private static class FragmentUtilActivity extends FragmentActivity {
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            LinearLayout view = new LinearLayout(this);
-            view.setId(1);
-
-            setContentView(view);
-        }
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java
new file mode 100644
index 0000000..10c9dfb
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/apppreference/AppPreferenceTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.apppreference;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class AppPreferenceTest {
+
+    private Context mContext;
+    private View mRootView;
+    private AppPreference mPref;
+    private PreferenceViewHolder mHolder;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mRootView = View.inflate(mContext, R.layout.preference_app, null /* parent */);
+        mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
+        mPref = new AppPreference(mContext);
+    }
+
+    @Test
+    public void setProgress_showProgress() {
+        mPref.setProgress(1);
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mHolder.findViewById(android.R.id.progress).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void setSummary_showSummaryContainer() {
+        mPref.setSummary("test");
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mHolder.findViewById(R.id.summary_container).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void noSummary_hideSummaryContainer() {
+        mPref.setSummary(null);
+        mPref.onBindViewHolder(mHolder);
+
+        assertThat(mHolder.findViewById(R.id.summary_container).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void foobar_testName() {
+        float iconSize = mContext.getResources().getDimension(R.dimen.secondary_app_icon_size);
+        assertThat(Float.floatToIntBits(iconSize)).isEqualTo(Float.floatToIntBits(32));
+    }
+}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index c53417b..de86789 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -55,7 +55,7 @@
     <bool name="def_networks_available_notification_on">true</bool>
 
     <bool name="def_backup_enabled">false</bool>
-    <string name="def_backup_transport" translatable="false">android/com.android.internal.backup.LocalTransport</string>
+    <string name="def_backup_transport" translatable="false">com.android.localtransport/.LocalTransport</string>
 
     <!-- Default value for whether or not to pulse the notification LED when there is a
          pending notification -->
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index bd21b83..8745a33 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -659,6 +659,9 @@
         dumpSetting(s, p,
                 Settings.Global.GPU_DEBUG_LAYERS,
                 GlobalSettingsProto.Gpu.DEBUG_LAYERS);
+        dumpSetting(s, p,
+                Settings.Global.ANGLE_ENABLED_APP,
+                GlobalSettingsProto.Gpu.ANGLE_ENABLED_APP);
         p.end(gpuToken);
 
         final long hdmiToken = p.start(GlobalSettingsProto.HDMI);
@@ -1140,6 +1143,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 63978ba..18ec9c3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -870,7 +870,11 @@
                 }
             }
             if (newRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
-                    != prevRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)) {
+                    != prevRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES) ||
+                    newRestrictions.getBoolean(
+                            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY)
+                    != prevRestrictions.getBoolean(
+                            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY)) {
                 final long identity = Binder.clearCallingIdentity();
                 try {
                     synchronized (mLock) {
@@ -3285,8 +3289,8 @@
                 if (currentVersion == 133) {
                     // Version 133: Add default end button behavior
                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
-                    if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR) ==
-                            null) {
+                    if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR)
+                            .isNull()) {
                         String defaultEndButtonBehavior = Integer.toString(getContext()
                                 .getResources().getInteger(R.integer.def_end_button_behavior));
                         systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index da870bd..ce503b3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -24,6 +24,7 @@
 
     <!-- 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_CONTACTS" />
@@ -151,6 +152,7 @@
 
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
     <uses-permission android:name="android.permission.SUSPEND_APPS" />
+    <uses-permission android:name="android.permission.READ_CLIPBOARD_IN_BACKGROUND" />
 
     <application android:label="@string/app_label"
                  android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index ec35b3d..2530abc 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -44,6 +44,7 @@
 
 import libcore.io.Streams;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ChooserActivity;
 import com.android.internal.logging.MetricsLogger;
@@ -234,6 +235,7 @@
      */
     private boolean mTakingScreenshot;
 
+    @GuardedBy("sNotificationBundle")
     private static final Bundle sNotificationBundle = new Bundle();
 
     private boolean mIsWatch;
@@ -1059,10 +1061,12 @@
     }
 
     private static Notification.Builder newBaseNotification(Context context) {
-        if (sNotificationBundle.isEmpty()) {
-            // Rename notifcations from "Shell" to "Android System"
-            sNotificationBundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                    context.getString(com.android.internal.R.string.android_system_label));
+        synchronized (sNotificationBundle) {
+            if (sNotificationBundle.isEmpty()) {
+                // Rename notifcations from "Shell" to "Android System"
+                sNotificationBundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+                        context.getString(com.android.internal.R.string.android_system_label));
+            }
         }
         return new Notification.Builder(context, NOTIFICATION_CHANNEL_ID)
                 .addExtras(sNotificationBundle)
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/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index 680f14b..0b1dab1 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -38,11 +38,12 @@
 public interface NotificationMenuRowPlugin extends Plugin {
 
     public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
-    public static final int VERSION = 4;
+    public static final int VERSION = 5;
 
     @ProvidesInterface(version = OnMenuEventListener.VERSION)
     public interface OnMenuEventListener {
         public static final int VERSION = 1;
+
         public void onMenuClicked(View row, int x, int y, MenuItem menu);
 
         public void onMenuReset(View row);
@@ -53,6 +54,7 @@
     @ProvidesInterface(version = MenuItem.VERSION)
     public interface MenuItem {
         public static final int VERSION = 1;
+
         public View getMenuView();
 
         public View getGutsView();
@@ -84,34 +86,136 @@
 
     public void setMenuClickListener(OnMenuEventListener listener);
 
-    public void setSwipeActionHelper(NotificationSwipeActionHelper listener);
-
     public void setAppName(String appName);
 
     public void createMenu(ViewGroup parent, StatusBarNotification sbn);
 
-    public View getMenuView();
-
-    public boolean isMenuVisible();
-
     public void resetMenu();
 
-    public void onTranslationUpdate(float translation);
+    public View getMenuView();
 
-    public void onHeightUpdate();
+    /**
+     * Get the target position that a notification row should be snapped open to in order to reveal
+     * the menu. This is generally determined by the number of icons in the notification menu and the
+     * size of each icon. This method accounts for whether the menu appears on the left or ride side
+     * of the parent notification row.
+     *
 
-    public void onNotificationUpdated(StatusBarNotification sbn);
+     * @return an int representing the x-offset in pixels that the notification should snap open to.
+     * Positive values imply that the notification should be offset to the right to reveal the menu,
+     * and negative alues imply that the notification should be offset to the right.
+     */
+    public int getMenuSnapTarget();
 
-    public boolean onTouchEvent(View view, MotionEvent ev, float velocity);
+    /**
+     * Determines whether or not the menu should be shown in response to user input.
+     * @return true if the menu should be shown, false otherwise.
+     */
+    public boolean shouldShowMenu();
+
+    /**
+     * Determines whether the menu is currently visible.
+     * @return true if the menu is visible, false otherwise.
+     */
+    public boolean isMenuVisible();
+
+    /**
+     * Determines whether a given movement is towards or away from the current location of the menu.
+     * @param movement
+     * @return true if the movement is towards the menu, false otherwise.
+     */
+    public boolean isTowardsMenu(float movement);
+
+    /**
+     * Determines whether the menu should snap closed instead of dismissing the
+     * parent notification, as a function of its current state.
+     *
+     * @return true if the menu should snap closed, false otherwise.
+     */
+    public boolean shouldSnapBack();
+
+    /**
+     * Determines whether the menu was previously snapped open to the same side that it is currently
+     * being shown on.
+     * @return true if the menu is snapped open to the same side on which it currently appears,
+     * false otherwise.
+     */
+    public boolean isSnappedAndOnSameSide();
+
+    /**
+     * Determines whether the notification the menu is attached to is able to be dismissed.
+     * @return true if the menu's parent notification is dismissable, false otherwise.
+     */
+    public boolean canBeDismissed();
+
+    /**
+     * Determines whether the menu should remain open given its current state, or snap closed.
+     * @return true if the menu should remain open, false otherwise.
+     */
+    public boolean isWithinSnapMenuThreshold();
+
+    /**
+     * Determines whether the menu has been swiped far enough to snap open.
+     * @return true if the menu has been swiped far enough to open, false otherwise.
+     */
+    public boolean isSwipedEnoughToShowMenu();
 
     public default boolean onInterceptTouchEvent(View view, MotionEvent ev) {
         return false;
     }
 
-    public default boolean useDefaultMenuItems() {
+    public default boolean shouldUseDefaultMenuItems() {
         return false;
     }
 
-    public default void onConfigurationChanged() {
-    }
+    /**
+     * Callback used to signal the menu that its parent's translation has changed.
+     * @param translation The new x-translation of the menu as a position (not an offset).
+     */
+    public void onParentTranslationUpdate(float translation);
+
+    /**
+     * Callback used to signal the menu that its parent's height has changed.
+     */
+    public void onParentHeightUpdate();
+
+    /**
+     * Callback used to signal the menu that its parent notification has been updated.
+     * @param sbn
+     */
+    public void onNotificationUpdated(StatusBarNotification sbn);
+
+    /**
+     * Callback used to signal the menu that a user is moving the parent notification.
+     * @param delta The change in the parent notification's position.
+     */
+    public void onTouchMove(float delta);
+
+    /**
+     * Callback used to signal the menu that a user has begun touching its parent notification.
+     */
+    public void onTouchStart();
+
+    /**
+     * Callback used to signal the menu that a user has finished touching its parent notification.
+     */
+    public void onTouchEnd();
+
+    /**
+     * Callback used to signal the menu that it has been snapped closed.
+     */
+    public void onSnapClosed();
+
+    /**
+     * Callback used to signal the menu that it has been snapped open.
+     */
+    public void onSnapOpen();
+
+    /**
+     * Callback used to signal the menu that its parent notification has been dismissed.
+     */
+    public void onDismiss();
+
+    public default void onConfigurationChanged() { }
+
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
index f6cf035..8db0d02 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
@@ -39,7 +39,7 @@
     /**
      * Call this to snap a notification to provided {@code targetLeft}.
      */
-    public void snap(View animView, float velocity, float targetLeft);
+    public void snapOpen(View animView, int targetLeft, float velocity);
 
     /**
      * Call this to snooze a notification based on the provided {@link SnoozeOption}.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
index aa2fb32..814324e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
@@ -20,6 +20,7 @@
 
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
+import java.io.PrintWriter;
 
 @ProvidesInterface(action = NavGesture.ACTION, version = NavGesture.VERSION)
 public interface NavGesture extends Plugin {
@@ -46,6 +47,8 @@
         public void onNavigationButtonLongPress(View v);
 
         public default void destroy() { }
+
+        public default void dump(PrintWriter pw) { }
     }
 
 }
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/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index c892ac3..b64e0cf 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -22,8 +22,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="3171996292755059205">"የቁልፍ ጥበቃ"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"ፒን ኮድ ይተይቡ"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"የሲም ፒዩኬ እና አዲሱን ፒን ኮድ ይተይቡ"</string>
-    <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"የሲም ፒዩኬ ኮድ"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"የሲም PUK እና አዲሱን ፒን ኮድ ይተይቡ"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"የሲም PUK ኮድ"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"አዲስ የሲም ፒን  ኮድ"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482"><font size="17">"የይለፍ ቃል ለመተየብ ይንኩ"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"ለመክፈት የይለፍ ቃል ይተይቡ"</string>
@@ -48,12 +48,12 @@
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="654102080186420706">"የማይሰራ ሲም ካርድ።"</string>
     <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"ሲም ካርድዎ እስከመጨረሻው ተሰናክሏል።\n ሌላ ሲም ካርድ ለማግኘት ከገመድ አልባ አገልግሎት አቅራቢዎ ጋር ይገናኙ።"</string>
     <string name="keyguard_sim_locked_message" msgid="953766009432168127">"ሲም ካርድ ተዘግቷል።"</string>
-    <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"ሲም ካርድ በፒዩኬ ተቆልፏል።"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"ሲም ካርድ በPUK ተቆልፏል።"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"ሲም ካርድን በመክፈት ላይ..."</string>
     <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"የፒን አካባቢ"</string>
     <string name="keyguard_accessibility_password" msgid="7695303207740941101">"የመሣሪያ ይለፍ ቃል"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"የሲም ፒን አካባቢ"</string>
-    <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"የሲም ፒዩኬ አካባቢ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"የሲም PUK አካባቢ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ቀጣዩ ማንቂያ ለ<xliff:g id="ALARM">%1$s</xliff:g> ተዘጋጅቷል"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ሰርዝ"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMን አሰናክል"</string>
@@ -74,14 +74,14 @@
     <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> መሣሪያን ያለሞባይል አገልግሎት ለመጠቀም eSIMን ያሰናክሉ።"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ፒን ያስገቡ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"የይለፍ ቃል ያስገቡ"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ሲም አሁን ተሰናክሏል። ለመቀጠል የፒዩኬ ኮድ ያስገቡ። ለዝርዝር አገልግሎት አቅራቢን ያግኙ።"</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"ሲም «<xliff:g id="CARRIER">%1$s</xliff:g>» አሁን ተሰናክሏል። ለመቀጠል የፒዩኬ ኮድ ያስገቡ። ዝርዝር መረጃን ለማግኘት የተንቀሳቃሽ ስልክ አገልግሎት አቅራቢውን ያነጋግሩ።"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ለዝርዝር አገልግሎት አቅራቢን ያግኙ።"</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"ሲም «<xliff:g id="CARRIER">%1$s</xliff:g>» አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ዝርዝር መረጃን ለማግኘት የተንቀሳቃሽ ስልክ አገልግሎት አቅራቢውን ያነጋግሩ።"</string>
     <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"የተፈለገውን የፒን ኮድ ያስገቡ"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"የተፈለገውን ፒን ኮድ ያረጋግጡ"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"ሲም ካርድን በመክፈት ላይ..."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ይተይቡ።"</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"የፒዩኬ ኮድ 8 ወይም ከዚያ በላይ ቁጥሮች ሊኖረው ይገባል።"</string>
-    <string name="kg_invalid_puk" msgid="5399287873762592502">"ትክክለኛውን የፒዩኬ ኮድ እንደገና ያስገቡ። ተደጋጋሚ ሙከራዎች ሲሙን እስከመጨረሻው ያሰናክሉታል።"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"የPUK ኮድ 8 ወይም ከዚያ በላይ ቁጥሮች ሊኖረው ይገባል።"</string>
+    <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">"ፒንዎን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልተየቡም። \n\nበ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
@@ -112,7 +112,7 @@
       <item quantity="other">ልክ ያልሆነ የሲም ፒዩኬ ኮድ፣ ሲሙ እስከመጨረሻው የማይሰራ ከመሆኑ በፊት <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
     </plurals>
     <string name="kg_password_pin_failed" msgid="8769990811451236223">"የሲም ፒን ክወና አልተሳካም!"</string>
-    <string name="kg_password_puk_failed" msgid="1331621440873439974">"የሲም ፒዩኬ ክወና አልተሳካም!"</string>
+    <string name="kg_password_puk_failed" msgid="1331621440873439974">"የሲም PUK ክወና አልተሳካም!"</string>
     <string name="kg_pin_accepted" msgid="7637293533973802143">"ኮዱ ተቀባይነት አግኝቷል!"</string>
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"ከአገልግሎት መስጫ ክልል ውጪ።"</string>
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"የግቤት ስልት ቀይር"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index b3b9732..50dc26b 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -117,13 +117,13 @@
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"Ingen dækning."</string>
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Skift indtastningsmetode"</string>
     <string name="airplane_mode" msgid="3807209033737676010">"Flytilstand"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Der skal angives et mønster efter genstart af enheden"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Du skal angive et mønster, når du har genstartet enheden"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Der skal indtastes en pinkode efter genstart af enheden"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Der skal indtastes en adgangskode efter genstart af enheden"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"Der kræves et mønster som ekstra beskyttelse"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"Der kræves en pinkode som ekstra beskyttelse"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"Der kræves en adgangskode som ekstra beskyttelse"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Der skal angives et mønster, når du skifter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Du skal angive et mønster, når du skifter profil"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Der skal indtastes en pinkode, når du skifter profil"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Der skal indtastes en adgangskode, når du skifter profil"</string>
     <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Enheden er blevet låst af administratoren"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index d5e36ce..f0c7e92 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -34,9 +34,9 @@
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Le code est incorrect."</string>
     <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Carte non valide."</string>
     <string name="keyguard_charged" msgid="3316115607283493413">"Complètement chargée"</string>
-    <string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rechargement…"</string>
-    <string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rechargement rapide…"</string>
-    <string name="keyguard_plugged_in_charging_slowly" msgid="509533586841478405">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rechargement lent…"</string>
+    <string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge…"</string>
+    <string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge rapide…"</string>
+    <string name="keyguard_plugged_in_charging_slowly" msgid="509533586841478405">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge lente…"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"Branchez votre chargeur."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"Appuyez sur \"Menu\" pour déverrouiller le clavier."</string>
     <string name="keyguard_network_locked_message" msgid="6743537524631420759">"Réseau verrouillé"</string>
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/drawable/biometric_dialog_bg.xml b/packages/SystemUI/res/drawable/biometric_dialog_bg.xml
new file mode 100644
index 0000000..335448d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/biometric_dialog_bg.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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/biometric_dialog_bg_color" />
+    <corners android:radius="1dp"
+        android:topLeftRadius="@dimen/biometric_dialog_corner_size"
+        android:topRightRadius="@dimen/biometric_dialog_corner_size"
+        android:bottomLeftRadius="0dp"
+        android:bottomRightRadius="0dp"/>
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_icon.xml b/packages/SystemUI/res/drawable/face_dialog_icon.xml
new file mode 100644
index 0000000..6d28b5a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/face_dialog_icon.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
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#000" android:pathData="M9,11.75A1.25,1.25 0 0,0 7.75,13A1.25,1.25 0 0,0 9,14.25A1.25,1.25 0 0,0 10.25,13A1.25,1.25 0 0,0 9,11.75M15,11.75A1.25,1.25 0 0,0 13.75,13A1.25,1.25 0 0,0 15,14.25A1.25,1.25 0 0,0 16.25,13A1.25,1.25 0 0,0 15,11.75M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,11.71 4,11.42 4.05,11.14C6.41,10.09 8.28,8.16 9.26,5.77C11.07,8.33 14.05,10 17.42,10C18.2,10 18.95,9.91 19.67,9.74C19.88,10.45 20,11.21 20,12C20,16.41 16.41,20 12,20Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_bg.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_bg.xml
deleted file mode 100644
index 221f170..0000000
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_bg.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="@color/fingerprint_dialog_bg_color" />
-    <corners android:radius="1dp"
-        android:topLeftRadius="@dimen/fingerprint_dialog_corner_size"
-        android:topRightRadius="@dimen/fingerprint_dialog_corner_size"
-        android:bottomLeftRadius="0dp"
-        android:bottomRightRadius="0dp"/>
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
index 83c1949..05fd467 100644
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
@@ -36,7 +36,7 @@
                         android:name="_R_G_L_2_G_D_0_P_0"
                         android:pathData=" M-25.36 -24.41 C-25.93,-24.31 -26.49,-24.27 -26.81,-24.27 C-28.11,-24.27 -29.35,-24.62 -30.43,-25.4 C-32.11,-26.6 -33.2,-28.57 -33.2,-30.79 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -47,7 +47,7 @@
                         android:name="_R_G_L_2_G_D_1_P_0"
                         android:pathData=" M-36.14 -21.78 C-37.15,-22.98 -37.72,-23.7 -38.51,-25.29 C-39.33,-26.94 -39.82,-28.78 -39.82,-30.77 C-39.82,-34.43 -36.85,-37.4 -33.19,-37.4 C-29.52,-37.4 -26.55,-34.43 -26.55,-30.77 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -58,7 +58,7 @@
                         android:name="_R_G_L_2_G_D_2_P_0"
                         android:pathData=" M-42.19 -25.68 C-42.95,-27.82 -43.09,-29.54 -43.09,-30.8 C-43.09,-32.27 -42.84,-33.65 -42.27,-34.9 C-40.71,-38.35 -37.24,-40.75 -33.2,-40.75 C-27.71,-40.75 -23.26,-36.3 -23.26,-30.8 C-23.26,-28.97 -24.74,-27.49 -26.57,-27.49 C-28.4,-27.49 -29.89,-28.97 -29.89,-30.8 C-29.89,-32.64 -31.37,-34.12 -33.2,-34.12 C-35.04,-34.12 -36.52,-32.64 -36.52,-30.8 C-36.52,-28.23 -35.53,-25.92 -33.92,-24.22 C-32.69,-22.93 -31.48,-22.12 -29.44,-21.53 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -69,7 +69,7 @@
                         android:name="_R_G_L_2_G_D_3_P_0"
                         android:pathData=" M-44.06 -38.17 C-42.87,-39.94 -41.39,-41.41 -39.51,-42.44 C-37.62,-43.47 -35.46,-44.05 -33.16,-44.05 C-30.88,-44.05 -28.72,-43.47 -26.85,-42.45 C-24.97,-41.43 -23.48,-39.97 -22.29,-38.21 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -80,7 +80,7 @@
                         android:name="_R_G_L_2_G_D_4_P_0"
                         android:pathData=" M-25.72 -45.45 C-27.99,-46.76 -30.43,-47.52 -33.28,-47.52 C-36.13,-47.52 -38.51,-46.74 -40.62,-45.45 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -97,7 +97,7 @@
                         android:name="_R_G_L_1_G_D_0_P_0"
                         android:pathData=" M0 -9 C4.97,-9 9,-4.97 9,0 C9,4.97 4.97,9 0,9 C-4.97,9 -9,4.97 -9,0 C-9,-4.97 -4.97,-9 0,-9c "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="2"
@@ -118,7 +118,7 @@
                         <path
                             android:name="_R_G_L_0_G_D_0_P_0"
                             android:fillAlpha="1"
-                            android:fillColor="@color/fingerprint_dialog_error_color"
+                            android:fillColor="@color/biometric_dialog_error_color"
                             android:fillType="nonZero"
                             android:pathData=" M1.1 3.94 C1.1,4.55 0.61,5.04 0,5.04 C-0.61,5.04 -1.1,4.55 -1.1,3.94 C-1.1,3.33 -0.61,2.84 0,2.84 C0.61,2.84 1.1,3.33 1.1,3.94c " />
                     </group>
@@ -131,7 +131,7 @@
                         <path
                             android:name="_R_G_L_0_G_D_0_P_1"
                             android:fillAlpha="1"
-                            android:fillColor="@color/fingerprint_dialog_error_color"
+                            android:fillColor="@color/biometric_dialog_error_color"
                             android:fillType="nonZero"
                             android:pathData=" M1 -4.06 C1,-4.06 1,-0.06 1,-0.06 C1,0.49 0.55,0.94 0,0.94 C-0.55,0.94 -1,0.49 -1,-0.06 C-1,-0.06 -1,-4.06 -1,-4.06 C-1,-4.61 -0.55,-5.06 0,-5.06 C0.55,-5.06 1,-4.61 1,-4.06c " />
                     </group>
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
index f682f87..fd0ab22 100644
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
@@ -36,7 +36,7 @@
                         android:name="_R_G_L_3_G_D_0_P_0"
                         android:pathData=" M-25.36 -24.41 C-25.93,-24.31 -26.49,-24.27 -26.81,-24.27 C-28.11,-24.27 -29.35,-24.62 -30.43,-25.4 C-32.11,-26.6 -33.2,-28.57 -33.2,-30.79 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -47,7 +47,7 @@
                         android:name="_R_G_L_3_G_D_1_P_0"
                         android:pathData=" M-36.14 -21.78 C-37.15,-22.98 -37.72,-23.7 -38.51,-25.29 C-39.33,-26.94 -39.82,-28.78 -39.82,-30.77 C-39.82,-34.43 -36.85,-37.4 -33.19,-37.4 C-29.52,-37.4 -26.55,-34.43 -26.55,-30.77 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -58,7 +58,7 @@
                         android:name="_R_G_L_3_G_D_2_P_0"
                         android:pathData=" M-42.19 -25.68 C-42.95,-27.82 -43.09,-29.54 -43.09,-30.8 C-43.09,-32.27 -42.84,-33.65 -42.27,-34.9 C-40.71,-38.35 -37.24,-40.75 -33.2,-40.75 C-27.71,-40.75 -23.26,-36.3 -23.26,-30.8 C-23.26,-28.97 -24.74,-27.49 -26.57,-27.49 C-28.4,-27.49 -29.89,-28.97 -29.89,-30.8 C-29.89,-32.64 -31.37,-34.12 -33.2,-34.12 C-35.04,-34.12 -36.52,-32.64 -36.52,-30.8 C-36.52,-28.23 -35.53,-25.92 -33.92,-24.22 C-32.69,-22.93 -31.48,-22.12 -29.44,-21.53 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -69,7 +69,7 @@
                         android:name="_R_G_L_3_G_D_3_P_0"
                         android:pathData=" M-44.06 -38.17 C-42.87,-39.94 -41.39,-41.41 -39.51,-42.44 C-37.62,-43.47 -35.46,-44.05 -33.16,-44.05 C-30.88,-44.05 -28.72,-43.47 -26.85,-42.45 C-24.97,-41.43 -23.48,-39.97 -22.29,-38.21 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -80,7 +80,7 @@
                         android:name="_R_G_L_3_G_D_4_P_0"
                         android:pathData=" M-25.72 -45.45 C-27.99,-46.76 -30.43,-47.52 -33.28,-47.52 C-36.13,-47.52 -38.51,-46.74 -40.62,-45.45 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_fingerprint_color"
+                        android:strokeColor="@color/biometric_dialog_biometric_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -101,7 +101,7 @@
                         android:name="_R_G_L_2_G_D_0_P_0"
                         android:pathData=" M-25.36 -24.41 C-25.93,-24.31 -26.49,-24.27 -26.81,-24.27 C-28.11,-24.27 -29.35,-24.62 -30.43,-25.4 C-32.11,-26.6 -33.2,-28.57 -33.2,-30.79 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -112,7 +112,7 @@
                         android:name="_R_G_L_2_G_D_1_P_0"
                         android:pathData=" M-36.14 -21.78 C-37.15,-22.98 -37.72,-23.7 -38.51,-25.29 C-39.33,-26.94 -39.82,-28.78 -39.82,-30.77 C-39.82,-34.43 -36.85,-37.4 -33.19,-37.4 C-29.52,-37.4 -26.55,-34.43 -26.55,-30.77 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -123,7 +123,7 @@
                         android:name="_R_G_L_2_G_D_2_P_0"
                         android:pathData=" M-42.19 -25.68 C-42.95,-27.82 -43.09,-29.54 -43.09,-30.8 C-43.09,-32.27 -42.84,-33.65 -42.27,-34.9 C-40.71,-38.35 -37.24,-40.75 -33.2,-40.75 C-27.71,-40.75 -23.26,-36.3 -23.26,-30.8 C-23.26,-28.97 -24.74,-27.49 -26.57,-27.49 C-28.4,-27.49 -29.89,-28.97 -29.89,-30.8 C-29.89,-32.64 -31.37,-34.12 -33.2,-34.12 C-35.04,-34.12 -36.52,-32.64 -36.52,-30.8 C-36.52,-28.23 -35.53,-25.92 -33.92,-24.22 C-32.69,-22.93 -31.48,-22.12 -29.44,-21.53 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -134,7 +134,7 @@
                         android:name="_R_G_L_2_G_D_3_P_0"
                         android:pathData=" M-44.06 -38.17 C-42.87,-39.94 -41.39,-41.41 -39.51,-42.44 C-37.62,-43.47 -35.46,-44.05 -33.16,-44.05 C-30.88,-44.05 -28.72,-43.47 -26.85,-42.45 C-24.97,-41.43 -23.48,-39.97 -22.29,-38.21 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -145,7 +145,7 @@
                         android:name="_R_G_L_2_G_D_4_P_0"
                         android:pathData=" M-25.72 -45.45 C-27.99,-46.76 -30.43,-47.52 -33.28,-47.52 C-36.13,-47.52 -38.51,-46.74 -40.62,-45.45 "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="1.45"
@@ -162,7 +162,7 @@
                         android:name="_R_G_L_1_G_D_0_P_0"
                         android:pathData=" M0 -9 C4.97,-9 9,-4.97 9,0 C9,4.97 4.97,9 0,9 C-4.97,9 -9,4.97 -9,0 C-9,-4.97 -4.97,-9 0,-9c "
                         android:strokeAlpha="1"
-                        android:strokeColor="@color/fingerprint_dialog_error_color"
+                        android:strokeColor="@color/biometric_dialog_error_color"
                         android:strokeLineCap="round"
                         android:strokeLineJoin="round"
                         android:strokeWidth="2"
@@ -183,7 +183,7 @@
                         <path
                             android:name="_R_G_L_0_G_D_0_P_0"
                             android:fillAlpha="1"
-                            android:fillColor="@color/fingerprint_dialog_error_color"
+                            android:fillColor="@color/biometric_dialog_error_color"
                             android:fillType="nonZero"
                             android:pathData=" M1.1 3.94 C1.1,4.55 0.61,5.04 0,5.04 C-0.61,5.04 -1.1,4.55 -1.1,3.94 C-1.1,3.33 -0.61,2.84 0,2.84 C0.61,2.84 1.1,3.33 1.1,3.94c " />
                     </group>
@@ -196,7 +196,7 @@
                         <path
                             android:name="_R_G_L_0_G_D_0_P_1"
                             android:fillAlpha="1"
-                            android:fillColor="@color/fingerprint_dialog_error_color"
+                            android:fillColor="@color/biometric_dialog_error_color"
                             android:fillType="nonZero"
                             android:pathData=" M1 -4.06 C1,-4.06 1,-0.06 1,-0.06 C1,0.49 0.55,0.94 0,0.94 C-0.55,0.94 -1,0.49 -1,-0.06 C-1,-0.06 -1,-4.06 -1,-4.06 C-1,-4.61 -0.55,-5.06 0,-5.06 C0.55,-5.06 1,-4.61 1,-4.06c " />
                     </group>
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/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml
new file mode 100644
index 0000000..0417e2e
--- /dev/null
+++ b/packages/SystemUI/res/layout/biometric_dialog.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="bottom"
+    android:background="@color/biometric_dialog_dim_color"
+    android:orientation="vertical">
+
+    <!-- This is not a Space since Spaces cannot be clicked -->
+    <View
+        android:id="@+id/space"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending
+         on horizontal/portrait orientation -->
+        <View
+            android:id="@+id/left_space"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"/>
+
+        <LinearLayout
+            android:id="@+id/dialog"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:elevation="2dp"
+            android:background="@drawable/biometric_dialog_bg">
+
+            <TextView
+                android:id="@+id/title"
+                android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="24dp"
+                android:layout_marginStart="24dp"
+                android:layout_marginTop="24dp"
+                android:gravity="@integer/biometric_dialog_text_gravity"
+                android:textSize="20sp"
+                android:maxLines="1"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:marqueeRepeatLimit="marquee_forever"
+                android:textColor="@color/biometric_dialog_text_dark_color"/>
+
+            <TextView
+                android:id="@+id/subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginStart="24dp"
+                android:layout_marginEnd="24dp"
+                android:gravity="@integer/biometric_dialog_text_gravity"
+                android:textSize="16sp"
+                android:maxLines="1"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:marqueeRepeatLimit="marquee_forever"
+                android:textColor="@color/biometric_dialog_text_dark_color"/>
+
+            <TextView
+                android:id="@+id/description"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="24dp"
+                android:layout_marginStart="24dp"
+                android:gravity="@integer/biometric_dialog_text_gravity"
+                android:paddingTop="8dp"
+                android:textSize="16sp"
+                android:maxLines="4"
+                android:textColor="@color/biometric_dialog_text_dark_color"/>
+
+            <ImageView
+                android:id="@+id/biometric_icon"
+                android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
+                android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="48dp"
+                android:scaleType="fitXY" />
+
+            <TextView
+                android:id="@+id/error"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="24dp"
+                android:layout_marginStart="24dp"
+                android:paddingTop="16dp"
+                android:paddingBottom="24dp"
+                android:textSize="12sp"
+                android:gravity="center_horizontal"
+                android:accessibilityLiveRegion="polite"
+                android:contentDescription="@string/accessibility_biometric_dialog_help_area"
+                android:textColor="@color/biometric_dialog_text_light_color"/>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="72dip"
+                android:paddingTop="24dp"
+                android:layout_gravity="center_vertical"
+                style="?android:attr/buttonBarStyle"
+                android:orientation="horizontal"
+                android:measureWithLargestChild="true">
+                <Space android:id="@+id/leftSpacer"
+                    android:layout_width="12dp"
+                    android:layout_height="match_parent"
+                    android:visibility="visible" />
+                <!-- Negative Button -->
+                <Button android:id="@+id/button2"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+                    android:gravity="center"
+                    android:maxLines="2" />
+                <Space android:id="@+id/middleSpacer"
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:visibility="visible" />
+                <!-- Positive Button -->
+                <Button android:id="@+id/button1"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    style="@*android:style/Widget.DeviceDefault.Button.Colored"
+                    android:gravity="center"
+                    android:maxLines="2"
+                    android:text="@string/biometric_dialog_confirm"
+                    android:visibility="gone"/>
+                <Space android:id="@+id/rightSpacer"
+                    android:layout_width="12dip"
+                    android:layout_height="match_parent"
+                    android:visibility="visible" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending
+         on horizontal/portrait orientation -->
+        <View
+            android:id="@+id/right_space"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent" />
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/fingerprint_dialog.xml b/packages/SystemUI/res/layout/fingerprint_dialog.xml
deleted file mode 100644
index 1bdaf6e..0000000
--- a/packages/SystemUI/res/layout/fingerprint_dialog.xml
+++ /dev/null
@@ -1,163 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="bottom"
-    android:background="@color/fingerprint_dialog_dim_color"
-    android:orientation="vertical">
-
-    <!-- This is not a Space since Spaces cannot be clicked -->
-    <View
-        android:id="@+id/space"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending
-         on horizontal/portrait orientation -->
-        <View
-            android:id="@+id/left_space"
-            android:layout_weight="1"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"/>
-
-        <LinearLayout
-            android:id="@+id/dialog"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:elevation="2dp"
-            android:background="@drawable/fingerprint_dialog_bg">
-
-            <TextView
-                android:id="@+id/title"
-                android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="24dp"
-                android:layout_marginStart="24dp"
-                android:layout_marginTop="24dp"
-                android:gravity="@integer/fingerprint_dialog_text_gravity"
-                android:textSize="20sp"
-                android:maxLines="1"
-                android:singleLine="true"
-                android:ellipsize="marquee"
-                android:marqueeRepeatLimit="marquee_forever"
-                android:textColor="@color/fingerprint_dialog_text_dark_color"/>
-
-            <TextView
-                android:id="@+id/subtitle"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dp"
-                android:layout_marginStart="24dp"
-                android:layout_marginEnd="24dp"
-                android:gravity="@integer/fingerprint_dialog_text_gravity"
-                android:textSize="16sp"
-                android:maxLines="1"
-                android:singleLine="true"
-                android:ellipsize="marquee"
-                android:marqueeRepeatLimit="marquee_forever"
-                android:textColor="@color/fingerprint_dialog_text_dark_color"/>
-
-            <TextView
-                android:id="@+id/description"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="24dp"
-                android:layout_marginStart="24dp"
-                android:gravity="@integer/fingerprint_dialog_text_gravity"
-                android:paddingTop="8dp"
-                android:textSize="16sp"
-                android:maxLines="4"
-                android:textColor="@color/fingerprint_dialog_text_dark_color"/>
-
-            <ImageView
-                android:id="@+id/fingerprint_icon"
-                android:layout_width="@dimen/fingerprint_dialog_fp_icon_size"
-                android:layout_height="@dimen/fingerprint_dialog_fp_icon_size"
-                android:layout_gravity="center_horizontal"
-                android:layout_marginTop="48dp"
-                android:scaleType="fitXY"
-                android:contentDescription="@string/accessibility_fingerprint_dialog_fingerprint_icon" />
-
-            <TextView
-                android:id="@+id/error"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="24dp"
-                android:layout_marginStart="24dp"
-                android:paddingTop="16dp"
-                android:paddingBottom="24dp"
-                android:textSize="12sp"
-                android:gravity="center_horizontal"
-                android:accessibilityLiveRegion="polite"
-                android:text="@string/fingerprint_dialog_touch_sensor"
-                android:contentDescription="@string/accessibility_fingerprint_dialog_help_area"
-                android:textColor="@color/fingerprint_dialog_text_light_color"/>
-
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="72dip"
-                android:paddingTop="24dp"
-                android:layout_gravity="center_vertical"
-                style="?android:attr/buttonBarStyle"
-                android:orientation="horizontal"
-                android:measureWithLargestChild="true">
-                <Space android:id="@+id/leftSpacer"
-                    android:layout_width="24dp"
-                    android:layout_height="match_parent"
-                    android:visibility="visible" />
-                <!-- Negative Button -->
-                <Button android:id="@+id/button2"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
-                    android:layout_marginStart="-12dp"
-                    android:gravity="start|center_vertical"
-                    android:maxLines="2" />
-                <!-- Positive Button -->
-                <Button android:id="@+id/button1"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
-                    android:layout_marginEnd="12dp"
-                    android:maxLines="2" />
-                <Space android:id="@+id/rightSpacer"
-                    android:layout_width="24dip"
-                    android:layout_height="match_parent"
-                    android:visibility="gone" />
-            </LinearLayout>
-        </LinearLayout>
-
-        <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending
-         on horizontal/portrait orientation -->
-        <View
-            android:id="@+id/right_space"
-            android:layout_weight="1"
-            android:layout_width="0dp"
-            android:layout_height="match_parent" />
-
-    </LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
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/qs_customize_panel_content.xml b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
index bb67c54..87b4551 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel_content.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
@@ -17,6 +17,7 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">->
     <View
+        android:id="@+id/customizer_transparent_view"
         android:layout_width="match_parent"
         android:layout_height="@*android:dimen/quick_qs_offset_height"
         android:background="@android:color/transparent" />
diff --git a/packages/SystemUI/res/layout/qs_detail_buttons.xml b/packages/SystemUI/res/layout/qs_detail_buttons.xml
index 03ed62b..75f43f9 100644
--- a/packages/SystemUI/res/layout/qs_detail_buttons.xml
+++ b/packages/SystemUI/res/layout/qs_detail_buttons.xml
@@ -26,6 +26,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginEnd="8dp"
+        android:minHeight="48dp"
         android:minWidth="132dp"
         android:textAppearance="@style/TextAppearance.QS.DetailButton"
         android:focusable="true" />
@@ -35,6 +36,7 @@
         style="@style/QSBorderlessButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:minHeight="48dp"
         android:minWidth="88dp"
         android:textAppearance="@style/TextAppearance.QS.DetailButton"
         android:focusable="true"/>
diff --git a/packages/SystemUI/res/layout/qs_paged_page.xml b/packages/SystemUI/res/layout/qs_paged_page.xml
index 07f0c83..a8960d9 100644
--- a/packages/SystemUI/res/layout/qs_paged_page.xml
+++ b/packages/SystemUI/res/layout/qs_paged_page.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/tile_page"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
     android:paddingStart="@dimen/notification_side_paddings"
     android:paddingEnd="@dimen/notification_side_paddings"
     android:clipChildren="false"
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index e96a09b..e44fbcf 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -19,16 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:clipChildren="false"
-    android:clipToPadding="false"
+    android:layout_weight="1"
+    android:clipChildren="true"
     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/recents_onboarding.xml b/packages/SystemUI/res/layout/recents_onboarding.xml
index adf1e74..2538612 100644
--- a/packages/SystemUI/res/layout/recents_onboarding.xml
+++ b/packages/SystemUI/res/layout/recents_onboarding.xml
@@ -37,7 +37,7 @@
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:layout_gravity="center_vertical"
-            android:textColor="@android:color/white"
+            android:textColor="?attr/wallpaperTextColor"
             android:textSize="16sp"/>
         <ImageView
             android:id="@+id/dismiss"
@@ -49,6 +49,7 @@
             android:layout_marginEnd="2dp"
             android:alpha="0.7"
             android:src="@drawable/ic_close_white"
+            android:tint="?attr/wallpaperTextColor"
             android:background="?android:attr/selectableItemBackgroundBorderless"
             android:contentDescription="@string/accessibility_desc_close"/>
     </LinearLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 44691c2..3077433 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"maak kamera oop"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Kies nuwe taakuitleg"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselleer"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Hulpboodskapgebied"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bevestig"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Raak die vingerafdruksensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukikoon"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Programikoon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Hulpboodskapgebied"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Soek tans vir jou …"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Gesig-ikoon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Versoenbaarheid-zoem se knoppie."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoem kleiner na groter skerm."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth gekoppel."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Berging"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Wenke"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Kitsprogramme"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Kitsprogramme hoef nie geïnstalleer te word nie."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> loop tans"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Program is oopgemaak sonder dat dit geïnstalleer is."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Program is oopgemaak sonder dat dit geïnstalleer is. Tik om meer te wete te kom."</string>
     <string name="app_info" msgid="6856026610594615344">"Programinligting"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Gaan na blaaier"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Gaan na web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobiele data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is af"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 966e4d7..c0c0952 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ካሜራ ክፈት"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"የአዲስ ተግባር አቀማመጥን ይምረጡ"</string>
     <string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"የእገዛ መልዕክት አካባቢ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"አረጋግጥ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"የጣት አሻራ ዳሳሹን ይንኩ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"የጣት አሻራ አዶ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"የመተግበሪያ አዶ"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"የእገዛ መልዕክት አካባቢ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"እርስዎን በመፈለግ ላይ…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"የፊት አዶ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"የተኳኋኝአጉላ አዝራር።"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"አነስተኛውን ማያ ወደ ትልቅ አጉላ።"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ብሉቱዝ ተያይዟል።"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"ቅጽበታዊ መተግበሪያዎች መጫን አያስፈልጋቸውም።"</string>
+    <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="2650669128861626071">"ወደ አሳሽ ሂድ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ወደ ድር ሂድ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"የተንቀሳቃሽ ስልክ ውሂብ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>— <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ጠፍቷል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 278b00a..f7d5184 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -107,10 +107,12 @@
     <string name="camera_label" msgid="7261107956054836961">"فتح الكاميرا"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"تحديد تنسيق جديد للمهمة"</string>
     <string name="cancel" msgid="6442560571259935130">"إلغاء"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"منطقة رسالة المساعدة"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"تأكيد"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"المس جهاز استشعار بصمات الإصبع"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"رمز بصمة الإصبع"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"رمز التطبيق"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"منطقة رسالة المساعدة"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"جارٍ البحث عن وجهك…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"رمز الوجه"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"زر تكبير/تصغير للتوافق."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"استخدام التكبير/التصغير لتحويل شاشة صغيرة إلى شاشة أكبر"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"تم توصيل البلوتوث."</string>
@@ -456,7 +458,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>
@@ -847,9 +849,11 @@
     <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_message" msgid="8116608994995104836">"لا تتطلب التطبيقات الفورية إجراء التثبيت."</string>
+    <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="2650669128861626071">"الانتقال إلى المتصفح"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"الانتقال إلى الويب"</string>
     <string name="mobile_data" msgid="7094582042819250762">"بيانات الجوّال"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"‏تم إيقاف شبكة Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 8912f15..895faf8 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"কেমেৰা খোলক"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"নতুন কাৰ্যৰ চানেকি বাছনি কৰক"</string>
     <string name="cancel" msgid="6442560571259935130">"বাতিল কৰক"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"সহায় বাৰ্তাৰ ক্ষেত্ৰ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"নিশ্চিত কৰক"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"এপ্লিকেশ্বন আইকন"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"সহায় বাৰ্তাৰ ক্ষেত্ৰ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"আপোনাৰ মুখমণ্ডল বিচাৰি আছে…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"মুখমণ্ডলৰ আইকন"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"উপযোগিতা অনুসৰি জুম কৰা বুটাম।"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"স্ক্ৰীণৰ আকাৰ ডাঙৰ কৰিবলৈ জুম কৰক।"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ব্লুটুথ সংযোগ হ\'ল।"</string>
@@ -344,7 +346,7 @@
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সীমা"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সকীয়নি"</string>
     <string name="quick_settings_work_mode_label" msgid="7608026833638817218">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
-    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"ৰাতিৰ লাইট"</string>
+    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"ৰাতিৰ পোহৰ"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"সূৰ্যাস্তত অন কৰক"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"সূৰ্যোদয়ৰ লৈকে"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>ত অন কৰক"</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"তাৎক্ষণিক এপসমূহক ইনষ্টল কৰাৰ প্ৰয়োজন নাই।"</string>
+    <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="2650669128861626071">"ব্ৰাউজাৰলৈ যাওক"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ৱেবলৈ যাওক"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ম\'বাইল ডেটা"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f0779fb..461a328 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"kemaranı açın"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Yeni tapşırıq sxemi seçin"</string>
     <string name="cancel" msgid="6442560571259935130">"Ləğv et"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Yardım mesajı bölməsi"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Təsdiq"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Barmaq izi sensoruna klikləyin"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmaq izi ikonası"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Tətbiq ikonası"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Yardım mesajı bölməsi"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Siz axtarılırsınız…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Üz işarəsi"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyğunluq zoom düyməsi."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha böyük ekranda uzaqlaşdır."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth qoşulub."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Yaddaş"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Məsləhətlər"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Ani Tətbiqlər"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Ani tətbiqlər quraşdırma tələb etmir."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> işləyir"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Quraşdırılmadan açılan tətbiq."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Quraşdırılmadan açılan tətbiq. Ətraflı məlumat üçün klikləyin."</string>
     <string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Brauzerə daxil edin"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Vebə keçin"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobil data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi deaktivdir"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 9dc6460..ade59ab 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -104,10 +104,12 @@
     <string name="camera_label" msgid="7261107956054836961">"otvori kameru"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Izaberi novi raspored zadataka"</string>
     <string name="cancel" msgid="6442560571259935130">"Otkaži"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Oblast poruke za pomoć"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potvrdi"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor za otisak prsta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Oblast poruke za pomoć"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona lica"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Dugme Zum kompatibilnosti."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zumiranje sa manjeg na veći ekran."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth je priključen."</string>
@@ -444,7 +446,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>
@@ -829,9 +831,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memorijski prostor"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Saveti"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant aplikacije"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant aplikacije ne zahtevaju instalaciju."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija se otvorila bez instaliranja."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija se otvorila bez instaliranja. Dodirnite da biste saznali više."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Idi na pregledač"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Idi na veb"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 9898dbd..bea5c3f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"адкрыць камеру"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Выберыце новы макет заданняў"</string>
     <string name="cancel" msgid="6442560571259935130">"Скасаваць"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Поле даведачнага паведамлення"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Пацвердзіць"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Дакраніцеся да сканера адбіткаў пальцаў"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок адбіткаў пальцаў"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Значок праграмы"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Вобласць даведачнага паведамлення"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ідзе пошук вашага твару…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Значок твару"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка сумяшчальнасці маштаба."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Маштабаванне малых элементаў для большага экрана."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-сувязь."</string>
@@ -450,7 +452,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>
@@ -837,9 +839,11 @@
     <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_message" msgid="8116608994995104836">"Імгненныя праграмы не патрабуюць усталёўкі."</string>
+    <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="2650669128861626071">"Перайсці ў браўзер"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Перайсці ў інтэрнэт"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Маб. перадача даных"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi выключаны"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a5506a3..c321593 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"отваряне на камерата"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Избиране на ново оформление за задачите"</string>
     <string name="cancel" msgid="6442560571259935130">"Отказ"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Област за помощно съобщение"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Потвърждаване"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Докоснете сензора за отпечатъци"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатък"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Икона на приложението"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Област за помощно съобщение"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Търсим ви…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Икона на лице"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Бутон за промяна на мащаба с цел съвместимост."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Промяна на мащаба на екрана от по-малък до по-голям."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth е включен."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"За мигновените приложения не се изисква инсталиране."</string>
+    <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="2650669128861626071">"Към браузъра"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Към мрежата"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобилни данни"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Функцията за Wi‑Fi е изключена"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 5d52103..138f2b0 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -31,7 +31,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>
@@ -49,7 +49,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">"ব্লুটুথ টিথার করা হয়েছে"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ইনপুট পদ্ধতিগুলি সেট আপ করুন"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ফিজিক্যাল কীবোর্ড"</string>
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ক্যামেরা খুলুন"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"নতুন কার্য লেআউট বেছে নিন"</string>
     <string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"সহায়তার মেসেজ দেখানোর জায়গা"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"কনফার্ম করুন"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"আঙ্গুলের ছাপের সেন্সর স্পর্শ করুন"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"আঙ্গুলের ছাপের আইকন"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"অ্যাপ্লিকেশনের আইকন"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"সহায়তার মেসেজ দেখানোর জায়গা"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"আপনার জন্য খোঁজা হচ্ছে…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ফেস আইকন"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"সামঞ্জস্যের জুম বোতাম৷"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ছোট থেকে বৃহৎ স্ক্রীণে জুম করুন৷"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ব্লুটুথ সংযুক্ত হয়েছে৷"</string>
@@ -174,7 +176,7 @@
     <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_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_gps_enabled" msgid="3511469499240123019">"GPS সক্ষম করা হয়েছে৷"</string>
@@ -334,7 +336,7 @@
       <item quantity="one">%dটি ডিভাইস</item>
       <item quantity="other">%dটি ডিভাইস</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>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -576,7 +579,7 @@
     <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="alarm_template" msgid="3980063409350522735">"<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>
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"হটস্পট"</string>
@@ -679,7 +682,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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"ঝটপট অ্যাপ ইনস্টল করার প্রয়োজন হয় না।"</string>
+    <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="2650669128861626071">"ব্রাউজারে যান"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ওয়েবে যান"</string>
     <string name="mobile_data" msgid="7094582042819250762">"মোবাইল ডেটা"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"ওয়াই ফাই বন্ধ আছে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 4527e9a..88115a5 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -104,10 +104,12 @@
     <string name="camera_label" msgid="7261107956054836961">"otvori kameru"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Odaberite novi raspored zadataka"</string>
     <string name="cancel" msgid="6442560571259935130">"Otkaži"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Prostor za poruku za pomoć"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potvrdite"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor za otisak prsta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona za otisak prsta"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Prostor za poruku za pomoć"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona lica"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Dugme za uvećavanje u slučaju nekompatibilnosti."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Uvećani prikaz manjeg ekrana na većem ekranu."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth je povezan."</string>
@@ -444,7 +446,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>
@@ -831,9 +833,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pohrana"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Savjeti"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant-aplikacije"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Za instant aplikacije nije potrebna instalacija"</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Pokrenuta je aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija je otvorena bez prethodne instalacije."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija je otvorena bez prethodne instalacije. Dodirnite da saznate više."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Idi na preglednik"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Idite na internet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Prijenos podataka"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"WiFi veza je isključena"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 23754ea..27f043a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"obre la càmera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecciona el disseny de la tasca nova"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel·la"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Àrea de missatge d\'ajuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirma"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor d\'empremtes digitals"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona d\'empremta digital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icona d\'aplicació"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Àrea de missatge d\'ajuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"S\'està cercant la teva cara…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icona facial"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botó de zoom de compatibilitat."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Amplia menys com més gran sigui la pantalla."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connectat."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Emmagatzematge"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Suggeriments"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplicacions instantànies"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"No cal instal·lar les aplicacions instantànies."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"S\'està executant <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"L\'aplicació s\'ha obert sense instal·lar-se."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"L\'aplicació s\'ha obert sense instal·lar-se. Toca per obtenir més informació."</string>
     <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ves al navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Ves al web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dades mòbils"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"La Wi-Fi està desactivada"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index e7583b5..7825ade 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"spustit fotoaparát"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Vybrat nové rozvržení úkolů"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Oblast pro zprávu nápovědy"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potvrdit"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotkněte se snímače otisků prstů"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otisku prstu"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikace"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Oblast pro zprávu nápovědy"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hledáme vás…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona obličeje"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačítko úpravy velikosti z důvodu kompatibility"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zvětšit menší obrázek na větší obrazovku."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Rozhraní Bluetooth je připojeno."</string>
@@ -450,7 +452,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>
@@ -837,9 +839,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Úložiště"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Tipy"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Okamžité aplikace"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Okamžité aplikace není třeba instalovat."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je spuštěna"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikace byla otevřena bez instalace."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikace byla otevřena bez instalace. Klepnutím zobrazíte další informace."</string>
     <string name="app_info" msgid="6856026610594615344">"O aplikaci"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Přejít do prohlížeče"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Přejít na web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilní data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je vypnuta"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 31634a9..7ddcb5a 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"åbn kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Vælg nyt opgavelayout"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuller"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Område med hjælpemeddelelse"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bekræft"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sæt fingeren på fingeraftrykslæseren"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeraftryk"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appens ikon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område med hjælpemeddelelse"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Forsøger at finde dig…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ansigt"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knap for kompatibilitetszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom mindre til større skærm."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tilsluttet."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagerplads"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Tips"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps kræver ingen installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> kører"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"En app blev åbnet uden at blive installeret."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"En app blev åbnet uden at blive installeret. Tryk for at få flere oplysninger."</string>
     <string name="app_info" msgid="6856026610594615344">"Appinfo"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Gå til en browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Gå til website"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er slået fra"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index aa6e449..cd20971 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"Kamera öffnen"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Neues Aufgabenlayout auswählen"</string>
     <string name="cancel" msgid="6442560571259935130">"Abbrechen"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Bereich für die Hilfemeldung"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bestätigen"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Berühre den Fingerabdrucksensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerabdruck-Symbol"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"App-Symbol"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Bereich für die Hilfemeldung"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Wir suchen nach dir…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Gesichtssymbol"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Schaltfläche für Kompatibilitätszoom"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom auf einen größeren Bildschirm"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Mit Bluetooth verbunden"</string>
@@ -444,13 +446,13 @@
     <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>
-    <string name="profile_owned_footer" msgid="8021888108553696069">"Profil wird möglicherweise überwacht."</string>
-    <string name="vpn_footer" msgid="2388611096129106812">"Das Netzwerk wird möglicherweise überwacht."</string>
-    <string name="branded_vpn_footer" msgid="2168111859226496230">"Das Netzwerk wird möglicherweise überwacht"</string>
+    <string name="profile_owned_footer" msgid="8021888108553696069">"Profil wird eventuell überwacht."</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"Das Netzwerk wird eventuell überwacht."</string>
+    <string name="branded_vpn_footer" msgid="2168111859226496230">"Das Netzwerk wird eventuell überwacht"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Das Gerät wird von deiner Organisation verwaltet und ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
@@ -461,7 +463,7 @@
     <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Das Gerät wird von <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet und ist mit VPNs verbunden"</string>
     <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Deine Organisation kann den Netzwerkverkehr in deinem Arbeitsprofil überwachen"</string>
     <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kann den Netzwerkverkehr in deinem Arbeitsprofil überwachen"</string>
-    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Das Netzwerk wird möglicherweise überwacht"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Das Netzwerk wird eventuell überwacht"</string>
     <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Das Gerät ist mit VPNs verbunden"</string>
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Arbeitsprofil verbunden mit <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Das persönliche Profil ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
@@ -827,9 +829,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Speicher"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hinweise"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant-Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Bei Instant-Apps ist keine vorherige Installation erforderlich."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> wird ausgeführt"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App wurde geöffnet, ohne vorher installiert zu werden."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App wurde geöffnet, ohne vorher installiert zu werden. Tippe, um weitere Informationen zu erhalten."</string>
     <string name="app_info" msgid="6856026610594615344">"App-Informationen"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Browser öffnen"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Web aufrufen"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobile Daten"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"WLAN ist deaktiviert"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 1a1c762..0a35aec 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"άνοιγμα φωτογραφικής μηχανής"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Επιλέξτε τη νέα διάταξη εργασίας"</string>
     <string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Περιοχή μηνυμάτων βοήθειας"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Επιβεβαίωση"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Εικονίδιο εφαρμογής"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Περιοχή μηνυμάτων βοήθειας"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Αναζήτηση για εσάς…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Εικονίδιο προσώπου"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Κουμπί εστίασης συμβατότητας."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Ζουμ από μικρότερη σε μεγαλύτερη οθόνη."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Το Bluetooth είναι συνδεδεμένο."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Αποθηκευτικός χώρος"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Συμβουλές"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Εφαρμογές"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Οι Instant Εφαρμογές δεν απαιτούν εγκατάσταση."</string>
+    <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="2650669128861626071">"Μετάβ. σε πρόγ. περ."</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Μετάβαση στον ιστό"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Δεδομένα κινητής τηλεφωνίας"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Το Wi-Fi είναι ανενεργό"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index c0afae6..7fe3d9d 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Help message area"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirm"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Face icon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hints"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 488c748..379e112 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Help message area"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirm"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Face icon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hints"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index c0afae6..7fe3d9d 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Help message area"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirm"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Face icon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hints"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index c0afae6..7fe3d9d 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Help message area"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirm"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Face icon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hints"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index f775bb1..5be13ea 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎open camera‎‏‎‎‏‎"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎Select new task layout‎‏‎‎‏‎"</string>
     <string name="cancel" msgid="6442560571259935130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎Help message area‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎Confirm‎‏‎‎‏‎"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎Touch the fingerprint sensor‎‏‎‎‏‎"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎Fingerprint icon‎‏‎‎‏‎"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎Application icon‎‏‎‎‏‎"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎Help message area‎‏‎‎‏‎"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‎Looking for you…‎‏‎‎‏‎"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎Face icon‎‏‎‎‏‎"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‎Compatibility zoom button.‎‏‎‎‏‎"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎Zoom smaller to larger screen.‎‏‎‎‏‎"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎Bluetooth connected.‎‏‎‎‏‎"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‎Storage‎‏‎‎‏‎"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎Hints‎‏‎‎‏‎"</string>
     <string name="instant_apps" msgid="6647570248119804907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎Instant Apps‎‏‎‎‏‎"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎Instant apps don\'t require installation.‎‏‎‎‏‎"</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ running‎‏‎‎‏‎"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‎App opened without being installed.‎‏‎‎‏‎"</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎App opened without being installed. Tap to learn more.‎‏‎‎‏‎"</string>
     <string name="app_info" msgid="6856026610594615344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎App info‎‏‎‎‏‎"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎Go to browser‎‏‎‎‏‎"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎Go to web‎‏‎‎‏‎"</string>
     <string name="mobile_data" msgid="7094582042819250762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎Mobile data‎‏‎‎‏‎"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="ID_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎ — ‎‏‎‎‏‏‎<xliff:g id="ID_2">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎Wi-Fi is off‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 31509dc..52b311b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecciona el nuevo diseño de la tarea."</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área de mensajes de ayuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícono de huella digital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícono de la aplicación"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área de mensajes de ayuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Autenticando tu rostro…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ícono de rostro"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamiento"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Sugerencias"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Apps instantáneas"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Las Apps instantáneas no requieren instalación."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"La app se abrió sin instalarse."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"La app se abrió sin instalarse. Presiona para obtener más información."</string>
     <string name="app_info" msgid="6856026610594615344">"Información de apps"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ir al navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Ir a la Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Datos móviles"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desactivado"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2cc3abd..0329430 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7164937344850004466">"IU del sistema"</string>
+    <string name="app_label" msgid="7164937344850004466">"UI del sistema"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Quitar de la lista"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Información de la aplicación"</string>
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Seleccionar diseño de tarea nueva"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área de mensaje de ayuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icono de huella digital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icono de aplicación"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área de mensaje de ayuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Buscando tu cara…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icono de cara"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
@@ -442,7 +444,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>
@@ -561,13 +563,13 @@
     <string name="output_service_bt" msgid="6224213415445509542">"Bluetooth"</string>
     <string name="output_service_wifi" msgid="3749735218931825054">"Wi‑Fi"</string>
     <string name="output_service_bt_wifi" msgid="4486837869988770896">"Bluetooth y Wi‑Fi"</string>
-    <string name="system_ui_tuner" msgid="708224127392452018">"Configurador de IU del sistema"</string>
+    <string name="system_ui_tuner" msgid="708224127392452018">"Configurador de UI del sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de batería insertado"</string>
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar el porcentaje del nivel de batería en el icono de la barra de estado cuando no se esté cargando"</string>
     <string name="quick_settings" msgid="10042998191725428">"Ajustes rápidos"</string>
     <string name="status_bar" msgid="4877645476959324760">"Barra de estado"</string>
     <string name="overview" msgid="4018602013895926956">"Aplicaciones recientes"</string>
-    <string name="demo_mode" msgid="2532177350215638026">"Modo de demostración de IU del sistema"</string>
+    <string name="demo_mode" msgid="2532177350215638026">"Modo de demostración de UI del sistema"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"Habilitar modo de demostración"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"Mostrar modo de demostración"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string>
@@ -584,12 +586,12 @@
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona Wi-Fi"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de trabajo"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Diversión solo para algunos"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"El configurador de IU del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
     <string name="got_it" msgid="2239653834387972602">"Entendido"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"¡Enhorabuena! El configurador de IU del sistema se ha añadido a Ajustes"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"¡Enhorabuena! El configurador de UI del sistema se ha añadido a Ajustes"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Quitar de Ajustes"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Quitar el configurador de IU del sistema de Ajustes y dejar de utilizar sus funciones?"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Quitar el configurador de UI del sistema de Ajustes y dejar de utilizar sus funciones?"</string>
     <string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en tu dispositivo"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Mostrar los segundos del reloj"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar a la duración de la batería."</string>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamiento"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Sugerencias"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplicaciones Instantáneas"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"No es necesario instalar las 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 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="2650669128861626071">"Ir al navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Ir a la Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Datos móviles"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> ‑ <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desactivado"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f22dc1a..80313e7 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ava kaamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Uue toimingu paigutuse valimine"</string>
     <string name="cancel" msgid="6442560571259935130">"Tühista"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Abisõnumi ala"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Kinnita"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Puudutage sõrmejäljeandurit"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sõrmejälje ikoon"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Rakenduse ikoon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Abisõnumi ala"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Otsitakse teid …"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Näoikoon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Sobivussuumi nupp."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Suumi suuremale ekraanile vähem."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth on ühendatud."</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Salvestusruum"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Vihjed"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Installimata avatavad rakendused"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Installimata avatavaid rakendusi pole vaja installida."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Rakendus <xliff:g id="APP">%1$s</xliff:g> töötab"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Rakendus avati installimata."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Rakendus avati installimata. Lisateabe saamiseks puudutage."</string>
     <string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ava brauser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Avage veebis"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobiilne andmeside"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"WiFi on välja lülitatud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 87dba92..9e19723 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ireki kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Hautatu zereginen diseinua"</string>
     <string name="cancel" msgid="6442560571259935130">"Utzi"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Laguntza-mezuaren eremua"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Berretsi"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sakatu hatz-marken sentsorea"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Hatz-markaren ikonoa"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Aplikazioaren ikonoa"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Laguntza-mezuaren eremua"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Zure bila…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Aurpegiaren ikonoa"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Zoom-bateragarritasunaren botoia."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Handiagotu pantaila txikia."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetootha konektatuta."</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memoria"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Aholkuak"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Zuzeneko aplikazioak"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Zuzeneko aplikazioak ez dira instalatu behar."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> exekutatzen ari da"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Ezer instalatu gabe ireki da aplikazioa."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ezer instalatu gabe ireki da aplikazioa. Sakatu informazio gehiago lortzeko."</string>
     <string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Joan arakatzailera"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Joan sarera"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Datu-konexioa"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi konexioa desaktibatuta dago"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 5411d3d..7ef324f 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -47,7 +47,7 @@
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"تنظیمات"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <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_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="bluetooth_tethered" msgid="7094101612161133267">"اتصال اینترنتی با بلوتوث تلفن همراه"</string>
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"باز کردن دوربین"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"انتخاب طرح‌بندی جدید کار"</string>
     <string name="cancel" msgid="6442560571259935130">"لغو"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"بخش پیام راهنما"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"تأیید"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"حسگر اثر انگشت را لمس کنید"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"نماد اثر انگشت"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"نماد برنامه"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"بخش پیام راهنما"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"درحال جستجوی شما…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"نماد چهره"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"دکمه بزرگ‌نمایی سازگار."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"بزرگ‌نمایی از صفحه‌های کوچک تا بزرگ."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"بلوتوث متصل است."</string>
@@ -440,7 +442,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>
@@ -539,14 +541,14 @@
     <string name="ring_toggle_title" msgid="3281244519428819576">"تماس‌ها"</string>
     <string name="volume_ringer_status_normal" msgid="4273142424125855384">"زنگ زدن"</string>
     <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"لرزش"</string>
-    <string name="volume_ringer_status_silent" msgid="6896394161022916369">"بی‌صدا"</string>
+    <string name="volume_ringer_status_silent" msgid="6896394161022916369">"صامت"</string>
     <string name="qs_status_phone_vibrate" msgid="204362991135761679">"تلفن در حالت لرزش است"</string>
     <string name="qs_status_phone_muted" msgid="5437668875879171548">"تلفن بی‌صدا است"</string>
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"‏%1$s. برای باصدا کردن ضربه بزنید."</string>
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"‏%1$s. برای تنظیم روی لرزش ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری بی‌صدا شوند."</string>
-    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. برای بی‌صدا کردن ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری بی‌صدا شوند."</string>
+    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. برای صامت کردن ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری صامت شود."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‏%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string>
-    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏%1$s. برای بی‌صدا کردن ضربه بزنید."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏%1$s. برای صامت کردن ضربه بزنید."</string>
     <string name="volume_ringer_hint_mute" msgid="9199811307292269601">"صامت کردن"</string>
     <string name="volume_ringer_hint_unmute" msgid="6602880133293060368">"باصدا کردن"</string>
     <string name="volume_ringer_hint_vibrate" msgid="4036802135666515202">"لرزش"</string>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"برنامه‌های فوری نیاز به نصب ندارند."</string>
+    <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="2650669128861626071">"رفتن به مرورگر"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"رفتن به وب"</string>
     <string name="mobile_data" msgid="7094582042819250762">"داده تلفن همراه"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"‏Wi-Fi خاموش است"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 83345b8..dd82e08 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"avaa kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Valitse uusi tehtävien asettelu"</string>
     <string name="cancel" msgid="6442560571259935130">"Peruuta"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Ohjeviestialue"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Vahvista"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Kosketa sormenjälkitunnistinta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sormenjälkikuvake"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Sovelluskuvake"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Ohjeviestialue"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Etsitään kasvoja…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Kasvokuvake"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Yhteensopivuuszoomaus-painike."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoomaa pienemmältä suuremmalle ruudulle."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth yhdistetty."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Tallennustila"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Vihjeet"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Pikasovelluksia ei tarvitse asentaa."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> on käynnissä"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Sovellus avattiin ilman asennusta."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Sovellus avattiin ilman asennusta. Katso lisätietoja napauttamalla."</string>
     <string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Siirry selaimeen"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Avaa verkossa"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobiilitiedonsiirto"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi on pois käytöstä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index c9c252f..f9a9165 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"Ouvrir l\'appareil photo"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Sélectionner un nouveau format de tâche"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Zone de message d\'aide"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmer"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touchez le capteur d\'empreintes digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icône de l\'application"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zone de message d\'aide"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Recherche de votre visage…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icône de visage"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Bouton \"Zoom de compatibilité\""</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilité avec la taille de l\'écran"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connecté"</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Stockage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Conseils"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Applications instantanées"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Les applications instantanées ne nécessitent pas d\'installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Application ouverte sans avoir été installée."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Application ouverte sans avoir été installée. Touchez ici pour en savoir plus."</string>
     <string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ouvrir le navigateur"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Accéder au Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Données cellulaires"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Le Wi-Fi est désactivé"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 4559854..297f8f4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ouvrir l\'appareil photo"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Sélectionner un nouveau plan de tâche"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Zone de message d\'aide"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmer"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Appuyez sur le lecteur d\'empreinte digitale"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icône d\'application"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zone de message d\'aide"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Recherche de votre visage…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icône représentant un visage"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Bouton \"Zoom de compatibilité\""</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilité avec la taille de l\'écran"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connecté"</string>
@@ -401,9 +403,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Aucune\ninterruption"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorité\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
-    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Rechargement… (rechargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
-    <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Rechargement rapide… (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
-    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Rechargement lent… (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge... (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge rapide… (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge lente… (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Changer d\'utilisateur"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Changer d\'utilisateur (utilisateur actuel : <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Utilisateur actuel : <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Espace de stockage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Astuces"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Applis instantanées"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Les applis instantanées ne nécessitent pas d\'installation."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Vous pouvez ouvrir cette application sans l\'installer."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Vous pouvez ouvrir cette application sans l\'installer. Appuyez pour en savoir plus."</string>
     <string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Accéder au navigateur"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Accéder au site Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Données mobiles"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi désactivé"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 9cb251e..bea5481 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Seleccionar novo deseño de tarefas"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área de mensaxes de axuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca o sensor de impresión dixital"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona de impresión dixital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icona de aplicación"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área de mensaxes de axuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Buscándote…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icona de cara"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidade"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilidade co tamaño da pantalla."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamento"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Consellos"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplicacións instantáneas"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"As aplicacións instantáneas non precisan instalación."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Estase executando <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Abriuse a aplicación sen ter que instalala."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Abriuse a aplicación sen ter que instalala. Tocar para obter máis información."</string>
     <string name="app_info" msgid="6856026610594615344">"Info. da aplicación"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ir ao navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Acceder á web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Datos móbiles"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>-<xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"A wifi está desactivada"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index df06cbe..fd2c102 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"કૅમેરો ખોલો"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"નવું કાર્ય લેઆઉટ પસંદ કરો"</string>
     <string name="cancel" msgid="6442560571259935130">"રદ કરો"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"સહાય સંદેશનું ક્ષેત્ર"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"કન્ફર્મ કરો"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ફિંગરપ્રિન્ટના સેન્સરને સ્પર્શ કરો"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ફિંગરપ્રિન્ટનું આઇકન"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ઍપ્લિકેશનનું આઇકન"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"સહાય સંદેશનું ક્ષેત્ર"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"તમારા માટે શોધી રહ્યાં છે..."</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ચહેરા આઇકન"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"સુસંગતતા ઝૂમ બટન."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"નાનીથી મોટી સ્ક્રીન પર ઝૂમ કરો."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"બ્લૂટૂથ કનેક્ટ થયું."</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"ઝટપટ ઍપ્લિકેશનો માટે ઇન્સ્ટૉલેશનની જરૂર નથી."</string>
+    <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="2650669128861626071">"બ્રાઉઝર પર જાઓ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"વેબ પર જાઓ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"મોબાઇલ ડેટા"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"વાઇ-ફાઇ બંધ છે"</string>
diff --git a/packages/SystemUI/res/values-h320dp/config.xml b/packages/SystemUI/res/values-h320dp/config.xml
deleted file mode 100644
index a9c19db..0000000
--- a/packages/SystemUI/res/values-h320dp/config.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
--->
-
-<resources>
-    <!-- The number of rows in the QuickSettings -->
-    <integer name="quick_settings_num_rows">2</integer>
-</resources>
diff --git a/packages/SystemUI/res/values-h600dp/config.xml b/packages/SystemUI/res/values-h600dp/config.xml
deleted file mode 100644
index 8616e3e..0000000
--- a/packages/SystemUI/res/values-h600dp/config.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
--->
-
-<resources>
-    <!-- The number of rows in the QuickSettings -->
-    <integer name="quick_settings_num_rows">3</integer>
-</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 46555a4..bf77c0d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"कैमरा खोलें"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नया कार्य लेआउट चुनें"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द करें"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"सहायता का मैसेज दिखाने की जगह"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"पुष्टि करें"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फ़िंगरप्रिंट सेंसर को छुएं"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फ़िंगरप्रिंट आइकॉन"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ऐप्लिकेशन आइकॉन"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"सहायता का मैसेज दिखाने की जगह"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"आपको पहचान रहा है…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"चेहरे का आइकॉन"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"संगतता ज़ूम बटन."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"छोटी से बड़ी स्‍क्रीन पर ज़ूम करें."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ब्लूटूथ कनेक्ट किया गया."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"झटपट ऐप्स के लिए इंस्टॉलेशन ज़रूरी नहीं है."</string>
+    <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="2650669128861626071">"ब्राउज़र पर जाएं"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"वेब पर जाएं"</string>
     <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"वाई-फ़ाई बंद है"</string>
diff --git a/packages/SystemUI/res/values-hi/strings_car.xml b/packages/SystemUI/res/values-hi/strings_car.xml
index 8820046..3beada5 100644
--- a/packages/SystemUI/res/values-hi/strings_car.xml
+++ b/packages/SystemUI/res/values-hi/strings_car.xml
@@ -20,8 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="car_guest" msgid="3738772168718508650">"मेहमान"</string>
-    <!-- no translation found for start_guest_session (7055742120180595689) -->
-    <skip />
+    <string name="start_guest_session" msgid="7055742120180595689">"मेहमान मोड"</string>
     <string name="car_add_user" msgid="5245196248349230898">"उपयोगकर्ता जोड़ें"</string>
     <string name="car_new_user" msgid="8142927244990323906">"नया उपयोगकर्ता"</string>
     <string name="user_add_user_message_setup" msgid="1791011504259527329">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं तो, उस व्यक्ति को अपनी जगह सेट करनी होती है."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 7ad2fe2..cf54bef 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -104,10 +104,12 @@
     <string name="camera_label" msgid="7261107956054836961">"otvaranje fotoaparata"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Odaberite novi izgled zadataka"</string>
     <string name="cancel" msgid="6442560571259935130">"Odustani"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Područje poruke za pomoć"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potvrdi"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor otiska prsta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Područje poruke za pomoć"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona lica"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb za kompatibilnost zumiranja."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zumiranje manjeg zaslona na veći."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth povezan."</string>
@@ -444,7 +446,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>
@@ -829,9 +831,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pohrana"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Savjeti"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant aplikacije"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant aplikacije nije potrebno instalirati."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Izvodi se aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija je otvorena bez instaliranja."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija je otvorena bez instaliranja. Dodirnite da biste saznali više."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Otvori preglednik"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Prijeđi na web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index f5fad27..534cabd 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"kamera megnyitása"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Új feladatelrendezés kiválasztása"</string>
     <string name="cancel" msgid="6442560571259935130">"Mégse"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Súgószöveg területe"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Megerősítés"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Érintse meg az ujjlenyomat-érzékelőt"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ujjlenyomat ikonja"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Alkalmazás ikonja"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Súgószöveg területe"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Keresem az Ön arcát…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Arcikon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kompatibilitási zoom gomb."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kicsinyítsen a nagyobb képernyőhöz."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth csatlakoztatva."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Tárhely"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Tippek"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Azonnali alkalmazások"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Az azonnali alkalmazásokat nem kell telepíteni."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"A(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás jelenleg fut"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Az alkalmazás telepítés nélkül lett megnyitva."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Az alkalmazás telepítés nélkül lett megnyitva. Ha további információra van szüksége, koppintson ide."</string>
     <string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ugrás a böngészőbe"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Tovább az internetre"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobiladatok"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"A Wi-Fi ki van kapcsolva"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 5eeca4c..3b4e773 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"բացել ֆոտոխցիկը"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Ընտրել առաջադրանքի նոր դասավորություն"</string>
     <string name="cancel" msgid="6442560571259935130">"Չեղարկել"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Օգնության հաղորդագրության դաշտ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Հաստատել"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Հպեք մատնահետքերի սկաներին"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Մատնահետքի պատկերակ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Հավելվածի պատկերակ"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Օգնության հաղորդագրության դաշտ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Դեմքի ճանաչում…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Դեմքի պատկերակ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Համատեղելիության խոշորացման կոճակը:"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Դիտափոխել փոքրից ավելի մեծ էկրան:"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-ը միացված է:"</string>
@@ -440,7 +442,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>
@@ -582,12 +584,12 @@
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Թեժ կետ"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Աշխատանքային պրոֆիլ"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի ընդունիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտատիրոջ միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտատիրոջ միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
     <string name="got_it" msgid="2239653834387972602">"Եղավ"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի ընդունիչը ավելացվել է կարգավորումներին"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի կարգավորիչը ավելացվել է կարգավորումներին"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Հեռացնել կարգավորումներից"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի ընդունիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի կարգավորիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
     <string name="activity_not_found" msgid="348423244327799974">"Հավելվածը տեղադրված չէ սարքի վրա"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Ցույց տալ ժամացույցի վայրկյանները"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Ցույց տալ ժամացույցի վայրկյանները կարգավիճակի տողում: Կարող է ազդել մարտկոցի աշխատանքի ժամանակի վրա:"</string>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"Ակնթարթային հավելվածները տեղադրում չեն պահանջում։"</string>
+    <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="2650669128861626071">"Անցնել դիտարկիչ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Բացեք համացանցում"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Բջջային ինտերնետ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi-ն անջատված է"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 5a61a64..ef5f2dc 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"buka kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pilih tata letak tugas baru"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Area pesan bantuan"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Konfirmasi"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sentuh sensor sidik jari"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon sidik jari"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikon aplikasi"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Area pesan bantuan"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Mencari wajah Anda…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikon wajah"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tombol perbesar/perkecil kompatibilitas."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Perbesar dari layar kecil ke besar."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tersambung."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Penyimpanan"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Petunjuk"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplikasi Instan"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikasi instan tidak perlu diinstal."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> berjalan"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikasi dapat dibuka tanpa perlu diinstal."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikasi dapat dibuka tanpa perlu diinstal. Tap untuk mempelajari lebih lanjut."</string>
     <string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Buka browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Buka di web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Data seluler"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi nonaktif"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index fb83ff07..7119cb1 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"opna myndavél"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Velja nýtt útlit verkefna"</string>
     <string name="cancel" msgid="6442560571259935130">"Hætta við"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Svæði hjálparskilaboða"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Staðfesta"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Snertu fingrafaralesarann"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingrafaratákn"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Forritstákn"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Svæði hjálparskilaboða"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Leitar að þér ..."</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Andlitstákn"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Hnappur fyrir samhæfisaðdrátt."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aðlaga forrit fyrir lítinn skjá að stærri skjá."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tengt."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Geymslurými"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Vísbendingar"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Skyndiforrit"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Skyndiforrit þurfa ekki uppsetningu."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> er í gangi"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Forrit opnað án þess að vera uppsett."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Forrit opnað án þess að vera uppsett. Ýttu til að fá frekari upplýsingar."</string>
     <string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Opna vafra"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Fara á vefinn"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Farsímagögn"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Slökkt á Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index c081eaa..99f413d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"apri fotocamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Seleziona un nuovo layout per le attività"</string>
     <string name="cancel" msgid="6442560571259935130">"Annulla"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Area dei messaggi di assistenza"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confermo"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tocca il sensore di impronte digitali"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona dell\'impronta digitale"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icona dell\'applicazione"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Area dei messaggi di assistenza"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"In attesa del volto…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icona volto"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Pulsante zoom compatibilità."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom inferiore per schermo più grande."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth collegato."</string>
@@ -349,8 +351,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>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Spazio di archiviazione"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Suggerimenti"</string>
     <string name="instant_apps" msgid="6647570248119804907">"App istantanee"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Le app istantanee non richiedono l\'installazione."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"App <xliff:g id="APP">%1$s</xliff:g> in esecuzione"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App aperta senza essere stata installata."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App aperta senza essere stata installata. Tocca per avere ulteriori informazioni."</string>
     <string name="app_info" msgid="6856026610594615344">"Informazioni app"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Vai al browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Vai sul Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dati mobili"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi disattivato"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index d3d18ae..ad2003d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"פתח את המצלמה"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"בחר פריסה חדשה להצגת משימות"</string>
     <string name="cancel" msgid="6442560571259935130">"ביטול"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"אזור הודעת עזרה"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"אישור"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"יש לגעת בחיישן טביעות האצבע"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"סמל טביעת אצבע"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"סמל אפליקציה"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"אזור הודעת עזרה"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"מחפש אותך…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"סמל הפנים"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"לחצן מרחק מתצוגה של תאימות."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"שנה מרחק מתצוגה של מסך קטן לגדול יותר."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"‏Bluetooth מחובר."</string>
@@ -194,7 +196,7 @@
     <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_desc_notification_shade" msgid="4690274844447504208">"לוח הודעות."</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>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"הגדרות"</string>
@@ -266,7 +268,7 @@
       <item quantity="other">יש בפנים עוד <xliff:g id="NUMBER_1">%s</xliff:g> הודעות.</item>
       <item quantity="one">יש בפנים עוד הודעה <xliff:g id="NUMBER_0">%s</xliff:g>.</item>
     </plurals>
-    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"הגדרות עבור הודעות"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"הגדרת התראות"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"הגדרות <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"המסך נעול כעת לרוחב."</string>
@@ -448,7 +450,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>
@@ -835,9 +837,11 @@
     <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_message" msgid="8116608994995104836">"אפליקציות אינסטנט לא דורשות התקנה."</string>
+    <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="2650669128861626071">"מעבר אל הדפדפן"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"התחבר לאינטרנט"</string>
     <string name="mobile_data" msgid="7094582042819250762">"נתונים סלולריים"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> ‏— <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"‏Wi-Fi כבוי"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 8377f07..81870e5 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"カメラを起動"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"新しいタスクレイアウトの選択"</string>
     <string name="cancel" msgid="6442560571259935130">"キャンセル"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"ヘルプ メッセージ領域"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"確認"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"指紋認証センサーをタップしてください"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋アイコン"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"アプリのアイコン"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ヘルプ メッセージ領域"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"顔を認証しています…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"顔アイコン"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"互換ズームボタン。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"小さい画面から大きい画面に拡大。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetoothに接続済み。"</string>
@@ -346,7 +348,7 @@
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"警告: 上限は<xliff:g id="DATA_LIMIT">%s</xliff:g>です"</string>
     <string name="quick_settings_work_mode_label" msgid="7608026833638817218">"仕事用プロファイル"</string>
-    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"読書灯"</string>
+    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"夜間モード"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"日の入りに ON"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"日の出まで"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> に ON"</string>
@@ -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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"ストレージ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"ヒント"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant Apps はインストールせずに利用できます。"</string>
+    <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="2650669128861626071">"ブラウザに移動"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ウェブページを開く"</string>
     <string name="mobile_data" msgid="7094582042819250762">"モバイルデータ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi は OFF です"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index fb880c7..7e71fbe 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"კამერის გახსნა"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ახალი ამოცანის განლაგების არჩევა"</string>
     <string name="cancel" msgid="6442560571259935130">"გაუქმება"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"დამხმარე შეტყობინების არე"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"დადასტურება"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"შეეხეთ თითის ანაბეჭდის სენსორს"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"თითის ანაბეჭდის ხატულა"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"აპლიკაციის ხატულა"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"დახმარების შეტყობინების არეალი"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"მიმდინარეობს თქვენი ძიება…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"სახის ხატულა"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"თავსებადი მასშტაბირების ღილაკი."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"შეცვალეთ პატარა ეკრანი უფრო დიდით."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth დაკავშირებულია."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"მყისიერი აპები ინსტალაციას არ საჭიროებს."</string>
+    <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="2650669128861626071">"ბრაუზერზე გადასვლა"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ვებზე გადასვლა"</string>
     <string name="mobile_data" msgid="7094582042819250762">"მობილური ინტერნეტი"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi გამორთულია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 6e372d7..89c7ff8 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"камераны ашу"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Жаңа тапсырма пішімін таңдау"</string>
     <string name="cancel" msgid="6442560571259935130">"Бас тарту"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Анықтама хабары аумағы"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Растау"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Саусақ ізін оқу сканерін түртіңіз"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Саусақ ізі белгішесі"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Қолданба белгішесі"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Анықтама хабары аумағы"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Бет ізделуде…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Бет белгішесі"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Үйлесімділік ұлғайту түймесі."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Үлкендеу экранда кішірейту."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth қосылған."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Жад"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Кеңестер"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Лездік қолданбаларды орнатудың қажеті жоқ."</string>
+    <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="2650669128861626071">"Браузерге өту"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Вебке өту"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобильдік деректер"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өшірулі"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index eb9ed61..4d0c97c 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"បើក​ម៉ាស៊ីន​ថត"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ជ្រើសប្លង់ភារកិច្ចថ្មី"</string>
     <string name="cancel" msgid="6442560571259935130">"បោះ​បង់​"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"តំបន់សារ​ជំនួយ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"បញ្ជាក់"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ប៉ះ​ឧបករណ៍​ចាប់ស្នាម​ម្រាមដៃ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"រូបតំណាង​ស្នាម​ម្រាមដៃ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"រូបតំណាង​កម្មវិធី"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"តំបន់សារ​ជំនួយ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"កំពុងស្វែងរកអ្នក…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"រូប​ផ្ទៃមុខ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ប៊ូតុង​ពង្រីក​ត្រូវ​គ្នា។"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ពង្រីក/បង្រួម​​អេក្រង់​ពី​​ទៅធំ"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"បាន​តភ្ជាប់​ប៊្លូធូស។"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"កម្មវិធី​ប្រើ​ភ្លាមៗ​មិន​តម្រូវ​ឲ្យ​មានការ​ដំឡើង​ទេ។"</string>
+    <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="2650669128861626071">"ចូល​ទៅ​កម្មវិធី​រុករក​តាម​អ៊ីនធឺណិត"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ចូលទៅកាន់បណ្តាញ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ទិន្នន័យ​ទូរសព្ទចល័ត"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi បាន​បិទ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index c63dbe9..45f6944 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ಹೊಸ ಕಾರ್ಯ ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡಿ"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"ಸಹಾಯ ಸಂದೇಶ ಪ್ರದೇಶ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"ದೃಢೀಕರಿಸಿ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ಅಪ್ಲಿಕೇಶನ್‌ ಐಕಾನ್‌"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ಸಹಾಯ ಸಂದೇಶ ಪ್ರದೇಶ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ನಿಮಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ಮುಖದ ಐಕಾನ್‌"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ಹೊಂದಾಣಿಕೆಯ ಝೂಮ್ ಬಟನ್."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ಚಿಕ್ಕ ಪರದೆಯಿಂದ ದೊಡ್ಡ ಪರದೆಗೆ ಝೂಮ್ ಮಾಡು."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ಬ್ಲೂಟೂತ್‌‌ ಸಂಪರ್ಕಗೊಂಡಿದೆ."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"ತತ್‌ಕ್ಷಣ ಆಪ್‌ಗಳಿಗೆ ಸ್ಥಾಪನೆಯ ಅಗತ್ಯವಿಲ್ಲ."</string>
+    <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="2650669128861626071">"ಬ್ರೌಸರ್‌ಗೆ ಹೋಗಿ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ವೆಬ್‌ಗೆ ಹೋಗಿ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ಮೊಬೈಲ್ ಡೇಟಾ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 77c983e..dfa2bb4 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"카메라 열기"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"새 작업 레이아웃 선택"</string>
     <string name="cancel" msgid="6442560571259935130">"취소"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"도움말 메시지 영역"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"확인"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"지문 센서를 터치하세요."</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"지문 아이콘"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"애플리케이션 아이콘"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"도움말 메시지 영역"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"찾는 중..."</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"얼굴 아이콘"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"호환성 확대/축소 버튼입니다."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"작은 화면을 큰 화면으로 확대합니다."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"블루투스가 연결되었습니다."</string>
@@ -410,13 +412,13 @@
     <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"프로필 표시"</string>
     <string name="user_add_user" msgid="5110251524486079492">"사용자 추가"</string>
     <string name="user_new_user_name" msgid="426540612051178753">"새 사용자"</string>
-    <string name="guest_nickname" msgid="8059989128963789678">"손님"</string>
+    <string name="guest_nickname" msgid="8059989128963789678">"게스트"</string>
     <string name="guest_new_guest" msgid="600537543078847803">"게스트 추가"</string>
-    <string name="guest_exit_guest" msgid="7187359342030096885">"손님 삭제"</string>
-    <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"손님을 삭제하시겠습니까?"</string>
+    <string name="guest_exit_guest" msgid="7187359342030096885">"게스트 삭제"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"게스트를 삭제하시겠습니까?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"삭제"</string>
-    <string name="guest_wipe_session_title" msgid="6419439912885956132">"손님 세션 다시 시작"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"게스트 세션 다시 시작"</string>
     <string name="guest_wipe_session_message" msgid="8476238178270112811">"세션을 계속 진행하시겠습니까?"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"다시 시작"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"예, 계속합니다."</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>
@@ -825,9 +827,11 @@
     <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_message" msgid="8116608994995104836">"인스턴트 앱은 설치가 필요하지 않습니다."</string>
+    <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="2650669128861626071">"브라우저로 이동"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"웹으로 이동"</string>
     <string name="mobile_data" msgid="7094582042819250762">"모바일 데이터"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>, <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi가 사용 중지됨"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index e334da4..fc8a7d2 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"камераны ачуу"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Жаңы тапшырманын планын тандаңыз"</string>
     <string name="cancel" msgid="6442560571259935130">"Жокко чыгаруу"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Жардам билдирүүсү"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Ырастоо"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Манжа изинин сенсорун басыңыз"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Манжа изинин сүрөтчөсү"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Колдонмонун сүрөтчөсү"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Жардам билдирүүсү"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Жүзүңүз изделүүдө…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Жүздүн сүрөтчөсү"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Масштабды сыйыштыруу баскычы."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Кичинекейди чоң экранга масштабдоо."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth байланышта"</string>
@@ -209,7 +211,7 @@
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Учак режими өчүрүлдү."</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Учак режими күйгүзүлдү."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"тымтырс"</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"ойготкучтар гана"</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"ойготкуч гана"</string>
     <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Тынчымды алба."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Тынчымды алба деген өчүрүлдү."</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Тынчымды алба деген күйгүзүлдү."</string>
@@ -276,7 +278,7 @@
     <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Кошумча параметрлерди ачуу үчүн сүрөтчөлөрдү басып, кармап туруңуз"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Тынчымды алба"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Шашылыш эскертмелер гана"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ойготкучтар гана"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ойготкуч гана"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Тымтырс"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> түзмөк)"</string>
@@ -395,7 +397,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Толук жымжырттык талап кылынат. Бул экрандагыны окугучтарды да тынчтандырат."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Тымтырс"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"Шашылыш эскертмелер гана"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"Ойготкучтар гана"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"Ойготкуч гана"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Тым-\nтырс"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Артыкчылыктуу\nгана"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ойготкучтар\nгана"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"Ыкчам ачылуучу колдонмолорду орнотуу талап кылынбайт."</string>
+    <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="2650669128861626071">"Серепчиге өтүү"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Интернетке өтүү"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобилдик Интернет"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өчүк"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 56f9e1d..1b8adcc 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ເປີດ​ກ້ອງ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ເລືອກ​ແຜນ​ຜັງ​ໜ້າ​ວຽກ​ໃໝ່"</string>
     <string name="cancel" msgid="6442560571259935130">"ຍົກເລີກ"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"ຊ່ວຍພື້ນທີ່ຂໍ້ຄວາມ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"ຢືນຢັນ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ໄອຄອນລາຍນິ້ວມື"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ໄອຄອນແອັບພລິເຄຊັນ"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ຊ່ວຍພື້ນທີ່ຂໍ້ຄວາມ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ກຳລັງຊອກຫາທ່ານ…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ໄອຄອນໃບໜ້າ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ປຸ່ມຊູມທີ່ໃຊ້ຮ່ວມກັນໄດ້."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ຊູມຈໍນ້ອຍໄປເປັນຈໍຂະຫນາດໃຫຍ່."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ເຊື່ອມຕໍ່ Bluetooth ແລ້ວ."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"ອິນສະແຕນແອັບບໍ່ຈຳເປັນຕ້ອງມີການຕິດຕັ້ງ."</string>
+    <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="2650669128861626071">"ໄປທີ່ໂປຣແກຣມທ່ອງເວັບ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ໄປທີ່ເວັບ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ອິນເຕີເນັດມືຖື"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ປິດຢູ່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index b8ae38b..2dccd89c 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>
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"atidaryti fotoaparatą"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pasirinkti naują užduoties išdėstymą"</string>
     <string name="cancel" msgid="6442560571259935130">"Atšaukti"</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="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Programos piktograma"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Pagalbos pranešimo sritis"</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 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>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Padidinti ekraną."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"„Bluetooth“ prijungtas."</string>
@@ -448,7 +450,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>
@@ -835,9 +837,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Saugykla"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Užuominos"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Akimirksniu įkeliamos programos"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Akimirksniu įkeliamų programų nereikia įdiegti."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ paleista"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Programa atidaryta jos neįdiegus."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Programa atidaryta jos neįdiegus. Palieskite, kad sužinotumėte daugiau."</string>
     <string name="app_info" msgid="6856026610594615344">"Programos informacija"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Eiti į naršyklę"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Eiti į žiniatinklį"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilieji duomenys"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>–<xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"„Wi-Fi“ išjungtas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4a0ee10..7c906ca 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -104,10 +104,12 @@
     <string name="camera_label" msgid="7261107956054836961">"atvērt kameru"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Atlasiet jaunu uzdevumu izkārtojumu"</string>
     <string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Palīdzības ziņojuma apgabals"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Apstiprināt"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Pieskarieties pirksta nospieduma sensoram"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pirksta nospieduma ikona"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Lietojumprogrammas ikona"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Palīdzības ziņojuma apgabals"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Notiek jūsu sejas meklēšana…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Sejas ikona"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Saderības tālummaiņas poga."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Veikt tālummaiņu no mazāka ekrāna uz lielāku."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth savienojums ir izveidots."</string>
@@ -444,7 +446,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>
@@ -829,9 +831,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Krātuve"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Padomi"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Tūlītējās lietotnes"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Tūlītējām lietotnēm nav nepieciešama instalēšana."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Lietotne <xliff:g id="APP">%1$s</xliff:g> darbojas"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Lai atvērtu šo lietotni, tā nav jāinstalē."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Lai atvērtu šo lietotni, tā nav jāinstalē. Pieskarieties, lai uzzinātu vairāk."</string>
     <string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Atvērt pārlūku"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Pāriet uz tīmekli"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilie dati"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ir izslēgts"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index bf9cc35..a5ffd0f 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"отвори камера"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Изберете нов распоред на задача"</string>
     <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Област за пораки за помош"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Потврди"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Допрете го сензорот за отпечатоци"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатоци"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Икона за апликацијата"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Поле за пораки за помош"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ве бараме вас…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Икона за лице"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Копче за компатибилност на зум."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Зумот е помал на поголем екран."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth е поврзан."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"Инстант апликациите нема потреба да се инсталираат."</string>
+    <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="2650669128861626071">"Одете на прелистувач"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Одете на интернет"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобилен интернет"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi е исклучено"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index fefd073..5abde4e 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ക്യാമറ തുറക്കുക"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"പുതിയ ടാസ്‌ക് ലേഔട്ട് തിരഞ്ഞെടുക്കുക"</string>
     <string name="cancel" msgid="6442560571259935130">"റദ്ദാക്കുക"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"സഹായ സന്ദേശ ഏരിയ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"സ്ഥിരീകരിക്കുക"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"വിരലടയാള സെൻസർ സ്‌പർശിക്കുക"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"വിരലടയാള ഐക്കൺ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ആപ്പ് ഐക്കൺ"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"സഹായ സന്ദേശ ഏരിയ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"നിങ്ങൾക്കായി തിരയുന്നു…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"മുഖത്തിന്റെ ഐക്കൺ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"അനുയോജ്യതാ സൂം ബട്ടൺ."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ചെറുതിൽ നിന്ന് വലിയ സ്‌ക്രീനിലേക്ക് സൂം ചെയ്യുക."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ബ്ലൂടൂത്ത് കണക്‌റ്റുചെയ്തു."</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"ഇൻസ്‌റ്റ‌ന്റ് ആപ്പിന് ഇൻസ്‌റ്റലേഷൻ ആവശ്യമില്ല."</string>
+    <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="2650669128861626071">"ബ്രൗസറിലേക്ക് പോവുക"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"വെബിൽ പോവുക"</string>
     <string name="mobile_data" msgid="7094582042819250762">"മൊബൈൽ ഡാറ്റ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"വൈഫൈ ഓഫാണ്"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index e86dc64..878e404 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -101,10 +101,12 @@
     <string name="camera_label" msgid="7261107956054836961">"камер нээх"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Шинэ ажиллах талбарыг сонгоно уу"</string>
     <string name="cancel" msgid="6442560571259935130">"Цуцлах"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Тусламжийн зурвасын хэсэг"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Баталгаажуулах"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Хурууны хээ мэдрэгчид хүрэх"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Хурууны хээний дүрс тэмдэг"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Аппын дүрс тэмдэг"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Туслах зурвасын хэсэг"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Таныг хайж байна…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Царайны дүрс тэмдэг"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Тохиромжтой өсгөх товч."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Жижгээс том дэлгэцрүү өсгөх."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth холбогдсон."</string>
@@ -438,7 +440,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>
@@ -821,9 +823,11 @@
     <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_message" msgid="8116608994995104836">"Шуурхай аппыг суулгах шаардлагагүй."</string>
+    <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="2650669128861626071">"Хөтчид очих"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Вэбэд очих"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобайл дата"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi унтраалттай байна"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index a9f9af4..5a8e022 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"कॅमेरा उघडा"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नवीन कार्य लेआउट निवडा"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द करा"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"मदत मेसेज परिसर"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"खात्री करा"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिंट सेन्सरला स्पर्श करा"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिंट आयकन"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"अॅप्लिकेशन आयकन"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"मदत मेसेज क्षेत्र"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"तुमच्यासाठी शोधत आहे…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"चेहरा आयकन"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"सुसंगतता झूम बटण."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"लहानपासून मोठ्‍या स्‍क्रीनवर झूम करा."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ब्लूटूथ कनेक्‍ट केले."</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"इन्सटंट अॅप्सना स्थापनेची आवश्यकता नसते."</string>
+    <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="2650669128861626071">"ब्राउझरवर जा"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"वेबवर जा"</string>
     <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"वाय-फाय बंद आहे"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 6ec7889..e6f7abb 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"buka kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pilih reka letak tugas baharu"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Bahagian mesej bantuan"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Sahkan"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sentuh penderia cap jari"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon cap jari"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikon aplikasi"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Bahagian mesej bantuan"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Mencari anda…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikon wajah"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butang zum keserasian."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Skrin zum lebih kecil kepada lebih besar."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth disambungkan."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storan"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Pembayang"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Apl Segera"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Apl segera tidak memerlukan pemasangan."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> sedang berjalan"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Apl dibuka tanpa dipasang."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Apl dibuka tanpa dipasang. Ketik untuk mengetahui lebih lanjut."</string>
     <string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Pergi ke penyemak imbas"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Pergi ke web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Data mudah alih"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi dimatikan"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 7afb3b9..1103b3c 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ကင်မရာ ဖွင့်ရန်"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"အလုပ်သစ်စီစဥ်မှုကို ရွေးပါ။"</string>
     <string name="cancel" msgid="6442560571259935130">"မလုပ်တော့"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"အကူအညီမက်ဆေ့ဂျ် နေရာ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"အတည်ပြုပါ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"လက်ဗွေအာရုံခံကိရိယာကို တို့ပါ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"လက်ဗွေ သင်္ကေတ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"အပလီကေးရှင်း သင်္ကေတ"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"အကူအညီမက်ဆေ့ဂျ် နေရာ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"သင့်ကို ရှာဖွေနေသည်…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"မျက်နှာသင်္ကေတ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"အံဝင်ခွင်ကျ ဇူးမ်ခလုတ်"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ဖန်သားပြင်ပေါ်တွင် အသေးမှအကြီးသို့ ဇူးမ်ဆွဲခြင်း"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ဘလူးတုသ်ချိတ်ဆက်ထားမှု"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"သိုလှောင်မှုများ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"အရိပ်အမြွက်များ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"ချက်ခြင်းသုံးအက်ပ်များကို ထည့်သွင်းစရာမလိုပါ။"</string>
+    <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="2650669128861626071">"ဘရောင်ဇာသို့ သွားပါ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ဝဘ်သို့ သွားရန်"</string>
     <string name="mobile_data" msgid="7094582042819250762">"မိုဘိုင်းဒေတာ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> —<xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ကို ပိတ်ထားသည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index b817877..5db7a3c 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"åpne kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Velg en ny utforming for oppgaver"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Område for hjelpemelding"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bekreft"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Trykk på fingeravtrykkssensoren"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeravtrykk"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appikon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område for hjelpemelding"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ser etter deg …"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ansiktikon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Zoomknapp for kompatibilitet."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom fra mindre til større skjerm."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth er tilkoblet."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagring"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hint"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Du trenger ikke å installere instant-apper."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> kjører"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Appen ble åpnet uten at den ble installert."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Appen ble åpnet uten at den ble installert. Trykk for å finne ut mer."</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Gå til nettleser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Gå til nettstedet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er av"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 6cc405f..e77c5cd 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"क्यामेरा खोल्नुहोस्"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नयाँ कार्य लेआउट चयन गर्नुहोस्"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द गर्नुहोस्"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"मद्दतसम्बन्धी सन्देशको क्षेत्र"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"पुष्टि गर्नुहोस्"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्‌"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिन्ट जनाउने आइकन"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"अनुप्रयोग जनाउने आइकन"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"मद्दतसम्बन्धी सन्देशको क्षेत्र"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"तपाईंलाई खोज्दै…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"अनुहारको आइकन"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"मिलाउने जुम बटन।"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"स्क्रिनलाई सानोबाट ठूलो पार्नुहोस्।"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ब्लुटुथ जडान भयो।"</string>
@@ -432,7 +434,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>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"तात्कालिक अनुप्रयोगहरूलाई स्थापना गर्नु पर्दैन|"</string>
+    <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="2650669128861626071">"ब्राउजरमा जानुहोस्"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"वेबमा जानुहोस्"</string>
     <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi‑Fi निष्क्रिय छ"</string>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
new file mode 100644
index 0000000..3ab6b56
--- /dev/null
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <style name="Theme.SystemUI.Dialog" parent="@android:style/Theme.DeviceDefault.Dialog" />
+
+    <style name="Theme.SystemUI.Dialog.Alert" parent="@*android:style/Theme.DeviceDefault.Dialog.Alert" />
+
+    <style name="Theme.SystemUI.Dialog.GlobalActions" parent="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen">
+        <item name="android:windowIsFloating">true</item>
+    </style>
+
+</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index e8c6f8d..58d7949 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"camera openen"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Nieuwe taakindeling selecteren"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Gebied voor Help-berichten"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bevestigen"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Raak de vingerafdruksensor aan"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukpictogram"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"App-pictogram"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Gebied voor Help-berichten"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Jouw gezicht zoeken…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Gezichtspictogram"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knop voor compatibiliteitszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kleiner scherm uitzoomen naar groter scherm."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-verbinding ingesteld."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Opslag"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Hints"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant-apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant-apps hoeven niet te worden geïnstalleerd."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> actief"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"App geopend zonder dat deze is geïnstalleerd."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"App geopend zonder dat deze is geïnstalleerd. Tik voor meer informatie."</string>
     <string name="app_info" msgid="6856026610594615344">"App-info"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ga naar browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Ga naar internet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobiele data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wifi is uitgeschakeld"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 277181f..9f4cedf 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"କ୍ୟାମେରା ଖୋଲନ୍ତୁ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ନୂଆ ଟାସ୍କ ଲେଆଉଟ୍‍ ଚୟନ କରନ୍ତୁ"</string>
     <string name="cancel" msgid="6442560571259935130">"କ୍ୟାନ୍ସଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"ସାହାଯ୍ୟ ମେସେଜ୍ କ୍ଷେତ୍ର"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ସେନସର୍‌କୁ ଛୁଅଁନ୍ତୁ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ଆଇକନ୍"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ଆପ୍ଲିକେଶନ୍‌ ଆଇକନ୍‌"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ହେଲ୍ପ ମେସେଜ୍ କ୍ଷେତ୍ର"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ଆପଣଙ୍କୁ ଚିହ୍ନଟ କରୁଛି…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ମୁହଁ ଆଇକନ୍"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"କମ୍ପାଟିବିଲିଟୀ ଜୁମ୍ ବଟନ୍।"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ଜୁମ୍ କରି ସ୍କ୍ରୀନ୍‌କୁ ଛୋଟରୁ ବଡ଼ କରନ୍ତୁ।"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ବ୍ଲୁ-ଟୂଥ୍‍‌ ସଂଯୋଗ କରାଯାଇଛି।"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"ଇନଷ୍ଟାଣ୍ଟ ଆପ୍‌ ଇନଷ୍ଟଲ୍‍ କରିବାର ଆବଶ୍ୟକତା ନାହିଁ"</string>
+    <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="2650669128861626071">"ବ୍ରାଉଜର୍‌କୁ ଯାଆନ୍ତୁ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ୱେବକୁ ଯାଆନ୍ତୁ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ମୋବାଇଲ୍‌ ଡାଟା"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"ୱାଇ-ଫାଇ ଅଫ୍‍ ଅଛି"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6509871..5a1fff4 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ਨਵਾਂ ਕੰਮ ਲੇਆਉਟ ਚੁਣੋ"</string>
     <string name="cancel" msgid="6442560571259935130">"ਰੱਦ ਕਰੋ"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"ਮਦਦ ਸੁਨੇਹਾ ਖੇਤਰ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"ਪੁਸ਼ਟੀ ਕਰੋ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪ੍ਰਤੀਕ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ਐਪਲੀਕੇਸ਼ਨ ਦਾ ਪ੍ਰਤੀਕ"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ਮਦਦ ਸੁਨੇਹਾ ਖੇਤਰ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ਤੁਹਾਡੀ ਪਛਾਣ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ਚਿਹਰਾ ਪ੍ਰਤੀਕ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ਅਨੁਰੂਪਤਾ ਜ਼ੂਮ ਬਟਨ।"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ਵੱਡੀ ਸਕ੍ਰੀਨ ਤੇ ਛੋਟਾ ਜ਼ੂਮ ਕਰੋ।"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth ਕਨੈਕਟ ਕੀਤੀ।"</string>
@@ -344,7 +346,7 @@
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ਸੀਮਾ"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ਚਿਤਾਵਨੀ"</string>
     <string name="quick_settings_work_mode_label" msgid="7608026833638817218">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
-    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"ਰਾਤਰੀ ਲਾਈਟ"</string>
+    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"ਰਾਤ ਦੀ ਰੋਸ਼ਨੀ"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"ਸੂਰਜ ਛਿਪਣ \'ਤੇ ਚਾਲੂ"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ਸੂਰਜ ਚੜ੍ਹਨ ਤੱਕ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਚਾਲੂ"</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"ਤਤਕਾਲ ਐਪਾਂ ਨੂੰ ਸਥਾਪਨਾ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
+    <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="2650669128861626071">"ਬ੍ਰਾਊਜ਼ਰ \'ਤੇ ਜਾਓ"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ਵੈੱਬ \'ਤੇ ਜਾਓ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 2959a8d..41bac38 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"otwórz aparat"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Wybierz nowy układ zadań"</string>
     <string name="cancel" msgid="6442560571259935130">"Anuluj"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Obszar komunikatu pomocy"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potwierdź"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotknij czytnika linii papilarnych"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odcisku palca"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacji"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Obszar komunikatu pomocy"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Szukam Cię…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona twarzy"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Przycisk powiększenia na potrzeby zgodności."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Powiększa mniejszy ekran do większego."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth połączony."</string>
@@ -448,7 +450,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>
@@ -835,9 +837,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pamięć wewnętrzna"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Wskazówki"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplikacje błyskawiczne"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikacji błyskawicznych nie trzeba instalować."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> działa"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikacja została otwarta bez zainstalowania."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacja została otwarta bez zainstalowania. Kliknij, by dowiedzieć się więcej."</string>
     <string name="app_info" msgid="6856026610594615344">"O aplikacji"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Otwórz przeglądarkę"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Wejdź na stronę internetową"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Komórkowa transmisja danych"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi jest wyłączone"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ba50c13..4c0df134 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir câmera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo layout da tarefa"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área da mensagem de ajuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícone do app"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área da mensagem de ajuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Procurando você…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ícone facial"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão de zoom da compatibilidade."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aumentar a tela com zoom."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado."</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Armazenamento"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Dicas"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Os Instant Apps não requerem instalação."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"O app é aberto sem precisar ser instalado."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"O app é aberto sem precisar ser instalado. Toque para saber mais."</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Abrir o navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Acessar a Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dados móveis"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"O Wi-Fi está desativado"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index a03dba2..81be3f6 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir câmara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo esquema de tarefa"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área da mensagem de ajuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressões digitais."</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícone de aplicação"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área da mensagem de ajuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"À sua procura…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ícone de rosto"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão zoom de compatibilidade."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom menor para ecrã maior."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth ligado."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Armazenamento"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Sugestões"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplicações instantâneas"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"As Aplicações instantâneas não requerem instalação."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"A aplicação é aberta sem ser instalada."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"A aplicação é aberta sem ser instalada. Toque para saber mais."</string>
     <string name="app_info" msgid="6856026610594615344">"Info. da aplicação"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Ir para o navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Aceder à Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dados móveis"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desativado"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ba50c13..4c0df134 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir câmera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo layout da tarefa"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Área da mensagem de ajuda"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícone do app"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área da mensagem de ajuda"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Procurando você…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ícone facial"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão de zoom da compatibilidade."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aumentar a tela com zoom."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado."</string>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Armazenamento"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Dicas"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Os Instant Apps não requerem instalação."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"O app é aberto sem precisar ser instalado."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"O app é aberto sem precisar ser instalado. Toque para saber mais."</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Abrir o navegador"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Acessar a Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dados móveis"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"O Wi-Fi está desativado"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 149803b..b5bd02d5 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -104,10 +104,12 @@
     <string name="camera_label" msgid="7261107956054836961">"deschideți camera foto"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selectați noul aspect pentru activitate"</string>
     <string name="cancel" msgid="6442560571259935130">"Anulați"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Zona mesajelor de ajutor"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confirmați"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Atingeți senzorul de amprente"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pictograma amprentă"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Pictograma aplicației"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zona mesajelor de ajutor"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Vă căutăm…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Pictograma chip"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Buton zoom pentru compatibilitate."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Faceți zoom de la o imagine mai mică la una mai mare."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Conectat prin Bluetooth."</string>
@@ -446,7 +448,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>
@@ -831,9 +833,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Stocare"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Indicii"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplicații instantanee"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Aplicațiile instantanee nu necesită instalare."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> rulează"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplicația a fost deschisă fără a fi instalată."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplicația a fost deschisă fără a fi instalată. Atingeți pentru a afla mai multe."</string>
     <string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Accesați browserul"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Accesați pe web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Date mobile"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Conexiunea Wi-Fi este dezactivată"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 7a756cd..23324a21 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"Открыть камеру."</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Выберите другой макет"</string>
     <string name="cancel" msgid="6442560571259935130">"Отмена"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Справочное сообщение"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Подтвердить"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Прикоснитесь к сканеру отпечатков пальцев."</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок отпечатка пальца"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Значок приложения"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Справочное сообщение"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Поиск лица…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Значок лица"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка масштабирования (режим совместимости)"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Уменьшение изображения для увеличения свободного места на экране."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-соединение установлено."</string>
@@ -450,7 +452,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>
@@ -837,9 +839,11 @@
     <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_message" msgid="8116608994995104836">"Приложения с мгновенным запуском не требуется устанавливать."</string>
+    <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="2650669128861626071">"Перейти в браузер"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Перейти в браузер"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Моб. Интернет"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Модуль Wi-Fi отключен"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index e29aeda..98b79be 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"කැමරාව විවෘත කරන්න"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"නව කාර්යය සැකැස්ම තෝරන්න"</string>
     <string name="cancel" msgid="6442560571259935130">"අවලංගු කරන්න"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"උදවු පණිවිඩ ප්‍රදේශය"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"තහවුරු කරන්න"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ඇඟිලි සලකුණු නිරූපකය"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"යෙදුම් නිරූපකය"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"උදවු පණිවිඩ ප්‍රදේශය"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ඔබව සොයමින්…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"මුහුණ නිරූපකය"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ගැළපෙන විශාලන බොත්තම."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"විශාල තිරය වෙත කුඩාව විශාලනය කරන්න."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"බ්ලූටූත් සම්බන්ධිතයි."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"ක්ෂණික යෙදුම් ස්ථාපනය කිරීම අවශ්‍ය නොවේ."</string>
+    <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="2650669128861626071">"බ්‍රවුසරය වෙත යන්න"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"වෙබය වෙත යන්න"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ජංගම දත්ත"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ක්‍රියා විරහිතයි"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 8193e3f..d871cb4 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"spustiť fotoaparát"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Vyberte nové rozloženie úlohy"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Oblasť správy pomocníka"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potvrdiť"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Klepnite na senzor odtlačkov prstov"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odtlačku prsta"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikácie"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Oblasť chybového hlásenia"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hľadáme vás…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona tváre"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačidlo úpravy veľkosti z dôvodu kompatibility."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zväčšiť menší obrázok na väčšiu obrazovku."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth pripojené."</string>
@@ -450,7 +452,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>
@@ -837,9 +839,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Úložisko"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Tipy"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Okamžité aplikácie"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Okamžité aplikácie nevyžadujú inštaláciu."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Aplikácia <xliff:g id="APP">%1$s</xliff:g> je spustená"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikácia bola otvorená bez inštalácie."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikácia bola otvorená bez inštalácie. Klepnutím zobrazíte ďalšie informácie."</string>
     <string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Otvoriť prehliadač"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Prejsť na internet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilné dáta"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Pripojenie Wi‑Fi je vypnuté"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 7169441..e8f04af 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"odpri fotoaparat"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Izberite novo postavitev opravil"</string>
     <string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Območje sporočila pomoči"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Potrdite"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotaknite se tipala prstnih odtisov"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona prstnih odtisov"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Območje sporočila pomoči"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Preverjanje vašega obraza …"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona obraza"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb povečave za združljivost."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Povečava manjšega na večji zaslon."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Povezava Bluetooth vzpostavljena."</string>
@@ -450,7 +452,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>
@@ -837,9 +839,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Shramba"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Namigi"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Nenamestljive aplikacije"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Nenamestljivih aplikacij ni treba namestiti."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se izvaja"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija je odprta brez namestitve."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija je odprta brez namestitve. Dotaknite se, če želite izvedeti več."</string>
     <string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Odpri brskalnik"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Pojdi v splet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podatki"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je izklopljen"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f2903ef..429e84d 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"hap kamerën"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Zgjidh strukturën e re të detyrës"</string>
     <string name="cancel" msgid="6442560571259935130">"Anulo"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Zona e mesazhit të ndihmës"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Konfirmo"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Prek sensorin e gjurmës së gishtit"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona e gjurmës së gishtit"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona e aplikacionit"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zona e mesazhit të ndihmës"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Po të kërkojmë…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ikona e fytyrës"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butoni i zmadhimit të pajtueshmërisë."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zmadho nga një ekran i vogël në të madh."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Pajisja është lidhur me \"bluetooth\"."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Hapësira ruajtëse"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Sugjerimet"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplikacionet e çastit"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikacionet e çastit nuk kërkojnë instalim."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Po ekzekutohet <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Aplikacioni u hap pa u instaluar."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacioni u hap pa u instaluar. Trokit për të mësuar më shumë."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Shko te shfletuesi"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Shko në ueb"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Të dhënat celulare"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi është joaktiv"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e77b080..a164876 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -104,10 +104,12 @@
     <string name="camera_label" msgid="7261107956054836961">"отвори камеру"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Изабери нови распоред задатака"</string>
     <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Област поруке за помоћ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Потврди"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Додирните сензор за отисак прста"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона отиска прста"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Икона апликације"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Област поруке за помоћ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Тражимо вас…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Икона лица"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Дугме Зум компатибилности."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Зумирање са мањег на већи екран."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth је прикључен."</string>
@@ -444,7 +446,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>
@@ -829,9 +831,11 @@
     <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_message" msgid="8116608994995104836">"Инстант апликације не захтевају инсталацију."</string>
+    <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="2650669128861626071">"Иди на прегледач"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Иди на веб"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобилни подаци"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi је искључен"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ccc498e..37614d9 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"öppna kameran"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Välj en ny layout för uppgiften"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Område för hjälpmeddelande"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Bekräfta"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tryck på fingeravtryckssensorn"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon för fingeravtryck"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appikon"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område för hjälpmeddelande"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Håller utkik efter dig …"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Ansiktsikon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knapp för kompatibilitetszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zooma mindre skärm till större."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth ansluten."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagring"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Tips"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Snabbappar"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Snabbappar behöver inte installeras."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> körs"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Appen öppnades utan installation."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Appen öppnades utan installation. Tryck om du vill veta mer."</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Öppna webbläsaren"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Öppna webbplatsen"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi är inaktiverat"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 83e9997..5cbd2db 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"fungua kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Chagua muundo mpya wa kazi"</string>
     <string name="cancel" msgid="6442560571259935130">"Ghairi"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Sehemu ya ujumbe wa usaidizi"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Thibitisha"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Gusa kitambua alama ya kidole"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Aikoni ya alama ya kidole"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Aikoni ya programu"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Sehemu ya ujumbe wa usaidizi"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Inakutafuta…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Aikoni ya uso"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kichupo cha kukuza kwa utangamanifu"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kuza kidogo kwa skrini kubwa."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth imeunganishwa."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Hifadhi"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Vidokezo"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Programu Zinazofunguka Papo Hapo"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Huhitaji kusakinisha programu zinazofunguka papo hapo."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> inaendelea kutumika"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Programu inafunguka bila kusakinishwa."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Programu inafunguka bila kusakinishwa. Gusa ili upate maelezo zaidi."</string>
     <string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Tumia kivinjari"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Nenda kwenye wavuti"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Data ya simu"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g><xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi imezimwa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 6f06ab5..1f498e6 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"கேமராவைத் திற"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"புதிய பணி தளவமைப்பைத் தேர்ந்தெடுக்கவும்"</string>
     <string name="cancel" msgid="6442560571259935130">"ரத்துசெய்"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"உதவிச் செய்திக்கான பகுதி"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"உறுதிப்படுத்துக"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"கைரேகை உணர்வியைத் தொடவும்"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"கைரேகை ஐகான்"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"பயன்பாட்டு ஐகான்"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"உதவிச் செய்திக்கான பகுதி"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"உங்கள் முகத்தைத் தேடுகிறது…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"முக ஐகான்"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"பொருந்துமாறு அளவை மாற்றும் பொத்தான்."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"சிறியதிலிருந்து பெரிய திரைக்கு அளவை மாற்றும்."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"புளூடூத் இணைக்கப்பட்டது."</string>
@@ -344,9 +346,9 @@
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> வரம்பு"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> எச்சரிக்கை"</string>
     <string name="quick_settings_work_mode_label" msgid="7608026833638817218">"பணி விவரம்"</string>
-    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"இரவு ஒளி"</string>
+    <string name="quick_settings_night_display_label" msgid="3577098011487644395">"நைட் லைட்"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"மாலையில் ஆன் செய்"</string>
-    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"சூரிய உதயம் வரை"</string>
+    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"காலை வரை"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>க்கு ஆன் செய்"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> வரை"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"இன்ஸ்டண்ட் பயன்பாடுகளுக்கு நிறுவல் தேவையில்லை."</string>
+    <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="2650669128861626071">"உலாவிக்குச் செல்"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"இணையத்திற்குச் செல்"</string>
     <string name="mobile_data" msgid="7094582042819250762">"மொபைல் டேட்டா"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"வைஃபை முடக்கத்தில் உள்ளது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 7c09699..6c8f728d3 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"కెమెరాను తెరువు"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"కొత్త విధి లేఅవుట్‌ను ఎంచుకోండి"</string>
     <string name="cancel" msgid="6442560571259935130">"రద్దు చేయి"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"సహాయ సందేశ ప్రాంతం"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"నిర్ధారించు"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"వేలిముద్ర సెన్సార్‌ను తాకండి"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"వేలిముద్ర చిహ్నం"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"అప్లికేషన్ చిహ్నం"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"సహాయ సందేశ ప్రాంతం"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"మీ కోసం చూస్తోంది…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ముఖ చిహ్నం"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"అనుకూలత జూమ్ బటన్."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"చిన్న స్క్రీన్ నుండి పెద్దదానికి జూమ్ చేయండి."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"బ్లూటూత్ కనెక్ట్ చేయబడింది."</string>
@@ -440,7 +442,8 @@
     <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>
+    <!-- no translation found for manage_notifications_text (2386728145475108753) -->
+    <skip />
     <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>
@@ -823,9 +826,11 @@
     <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_message" msgid="8116608994995104836">"తక్షణ అనువర్తనాలకు ఇన్‌స్టాలేషన్ అవసరం లేదు."</string>
+    <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="2650669128861626071">"బ్రౌజర్‌కు వెళ్లండి"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"వెబ్‌కు వెళ్లు"</string>
     <string name="mobile_data" msgid="7094582042819250762">"మొబైల్ డేటా"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ఆఫ్‌లో ఉంది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 1d59868..d72d2d6 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"เปิดกล้อง"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"เลือกรูปแบบงานใหม่"</string>
     <string name="cancel" msgid="6442560571259935130">"ยกเลิก"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"พื้นที่ข้อความช่วยเหลือ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"ยืนยัน"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"แตะเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ไอคอนลายนิ้วมือ"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ไอคอนแอปพลิเคชัน"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"พื้นที่ข้อความช่วยเหลือ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"กำลังหาใบหน้าคุณ…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"ไอคอนใบหน้า"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ปุ่มซูมที่ใช้งานร่วมกันได้"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ซูมหน้าจอให้มีขนาดใหญ่ขึ้น"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"เชื่อมต่อบลูทูธแล้ว"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"พื้นที่เก็บข้อมูล"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"คำแนะนำ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant App"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Instant Apps ไม่ต้องใช้การติดตั้ง"</string>
+    <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="2650669128861626071">"ไปที่เบราว์เซอร์"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ไปที่เว็บ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"เน็ตมือถือ"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ปิดอยู่"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 013acd4..c67aca4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"buksan ang camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pumili ng bagong layout ng gawain"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Lugar ng mensahe ng tulong"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Kumpirmahin"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Pindutin ang fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icon ng fingerprint"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icon ng application"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Lugar ng mensahe ng tulong"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hinahanap ka…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Face icon"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Button ng zoom ng pagiging tugma."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Mag-zoom nang mas maliit sa mas malaking screen."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Nakakonekta ang Bluetooth."</string>
@@ -346,7 +348,7 @@
     <string name="quick_settings_work_mode_label" msgid="7608026833638817218">"Profile sa trabaho"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Night Light"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Mao-on sa sunset"</string>
-    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hanggang mag-umaga"</string>
+    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hanggang sunrise"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Mao-on sa ganap na <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hanggang <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Mga Hint"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Hindi kailangang i-install ang mga instant na app."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"Tumatakbo ang <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Nabuksan ang app nang hindi ini-install."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Nabuksan ang app nang hindi ini-install. I-tap para matuto pa."</string>
     <string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Pumunta sa browser"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Pumunta sa web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Naka-off ang Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 9030113..edb9262 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"kamerayı aç"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Yeni görev düzenini seçin"</string>
     <string name="cancel" msgid="6442560571259935130">"İptal"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Yardım mesajı alanı"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Onaylayın"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Parmak izi sensörüne dokunun"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Parmak izi simgesi"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Uygulama simgesi"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Yardım mesajı alanı"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Yüzünüz tanınmaya çalışılıyor…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Yüz simgesi"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyumluluk zum düğmesi."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha büyük ekrana daha küçük yakınlaştır."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth bağlandı."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Depolama alanı"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"İpuçları"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Hazır Uygulamalar"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Hazır uygulamaların yüklenmesi gerekmez."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> çalışıyor"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Uygulama yüklenmeden açıldı."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Uygulama yüklenmeden açıldı. Daha fazla bilgi için dokunun."</string>
     <string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Tarayıcıya git"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Web\'e git"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobil veriler"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Kablosuz bağlantı kapalı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index cf21c0f..3d82520 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -105,10 +105,12 @@
     <string name="camera_label" msgid="7261107956054836961">"відкрити камеру"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Виберіть новий макет завдання"</string>
     <string name="cancel" msgid="6442560571259935130">"Скасувати"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Область довідкового повідомлення"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Підтвердити"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Торкніться сканера відбитків пальців"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок відбитка пальця"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Значок додатка"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Область довідкового повідомлення"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Пошук обличчя…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Значок обличчя"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка масштабування сумісності."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Збільшення екрана."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth під’єднано."</string>
@@ -450,7 +452,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>
@@ -837,9 +839,11 @@
     <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_message" msgid="8116608994995104836">"Додатки з миттєвим запуском не потрібно встановлювати."</string>
+    <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="2650669128861626071">"Веб-переглядач"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Перейти на веб-сайт"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Мобільний трафік"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi вимкнено"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index d2ee8c7..6b9c737 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"کیمرا کھولیں"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"نئے کام کا لے آؤٹ منتخب کریں"</string>
     <string name="cancel" msgid="6442560571259935130">"منسوخ کریں"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"امدادی پیغام کا علاقہ"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"تصدیق کریں"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"فنگر پرنٹ سینسر پر ٹچ کریں"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"فنگر پرنٹ آئیکن"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ایپلیکیشن کا آئیکن"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"امدادی پیغام کا علاقہ"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"آپ کے لیے تلاش کیا جا رہا ہے…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"چہرے کا آئیکن"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"مطابقت پذیری زوم بٹن۔"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"چھوٹی سے بڑی اسکرین پر زوم کریں۔"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"بلوٹوتھ مربوط ہے۔"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"فوری ایپس کو انسٹالیشن کی ضرورت نہیں ہے۔"</string>
+    <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="2650669128861626071">"براؤزر پر جائیں"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"ویب پر جائیں"</string>
     <string name="mobile_data" msgid="7094582042819250762">"موبائل ڈیٹا"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"‏Wi-Fi آف ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 2c45ab8..e2b5df4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"kamerani ochish"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Yangi vazifa tartibini tanlash"</string>
     <string name="cancel" msgid="6442560571259935130">"Bekor qilish"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Yordam xabari"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"OK"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Barmoq izi skaneriga tegining"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmoq izi belgisi"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ilova belgisi"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Yordam xabari"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Yuzingiz tekshirilmoqda…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Yuz belgisi"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kattalashtirish tugmasi mosligi."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kattaroq ekran uchun kichikroqni kattalashtirish."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth ulandi."</string>
@@ -160,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>
@@ -442,7 +444,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>
@@ -825,9 +827,11 @@
     <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_message" msgid="8116608994995104836">"Darhol ochiladigan ilovalarni o‘rnatish shart emas."</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 uchun bu yerga bosing."</string>
     <string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Brauzerni ochish"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Brauzerga o‘tish"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobil internet"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi o‘chiq"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 8c5e10d..8f98557 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"mở máy ảnh"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Chọn bố cục tác vụ mới"</string>
     <string name="cancel" msgid="6442560571259935130">"Hủy"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Vùng thông báo trợ giúp"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Xác nhận"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Chạm vào cảm biến vân tay"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Biểu tượng vân tay"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Biểu tượng ứng dụng"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Vùng thông báo trợ giúp"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Đang tìm kiếm bạn…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Biểu tượng khuôn mặt"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Nút thu phóng khả năng tương thích."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Thu phóng màn hình lớn hơn hoặc nhỏ hơn."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Đã kết nối bluetooth."</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Bộ nhớ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Gợi ý"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Ứng dụng tức thì"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Ứng dụng tức thì không yêu cầu cài đặt."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> đang chạy"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Ứng dụng được mở mà không cần cài đặt."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ứng dụng được mở mà không cần cài đặt. Nhấn để tìm hiểu thêm."</string>
     <string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Đi tới trình duyệt"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Truy cập web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dữ liệu di động"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi tắt"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6259bfd..27cad95 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"打开相机"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"选择新的任务布局"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"帮助消息区域"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"确认"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"请触摸指纹传感器"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指纹图标"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"应用图标"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"帮助消息区域"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在查找中…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"面孔图标"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"兼容性缩放按钮。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"将小屏幕的图片放大在较大屏幕上显示。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"蓝牙已连接。"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"免安装应用无需安装就能使用。"</string>
+    <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="2650669128861626071">"转到浏览器"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"转到网页版"</string>
     <string name="mobile_data" msgid="7094582042819250762">"移动数据"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"WLAN 已关闭"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index aa19f4f..da768b6 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"開啟相機"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"選取新的工作版面配置"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"說明訊息區域"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"確認"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"請輕觸指紋感應器"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"應用程式圖示"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"說明訊息區域"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在搜尋您的臉孔…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"面孔圖示"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"相容性縮放按鈕。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"將較小螢幕的畫面放大在較大螢幕上顯示。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"藍牙連線已建立。"</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>
@@ -825,9 +827,11 @@
     <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_message" msgid="8116608994995104836">"即時應用程式無需安裝即可使用。"</string>
+    <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="2650669128861626071">"前往瀏覽器"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"前往網頁版"</string>
     <string name="mobile_data" msgid="7094582042819250762">"流動數據"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi 已關閉"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 363c610..116f98b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"開啟攝影機"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"選取新工作版面配置"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"說明訊息區域"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"確認"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"請輕觸指紋感應器"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"應用程式圖示"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"說明訊息區域"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在尋找你的臉孔…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"臉孔圖示"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"相容性縮放按鈕。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"將較小螢幕的畫面放大在較大螢幕上顯示。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"藍牙連線已建立。"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <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_message" msgid="8116608994995104836">"免安裝應用程式不必安裝就能使用。"</string>
+    <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="2650669128861626071">"前往瀏覽器"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"前往網頁版"</string>
     <string name="mobile_data" msgid="7094582042819250762">"行動數據"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi 已關閉"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 0e4729b..53d3b9c 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -103,10 +103,12 @@
     <string name="camera_label" msgid="7261107956054836961">"vula ikhamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Khetha isakhiwo somsebenzi omusha"</string>
     <string name="cancel" msgid="6442560571259935130">"Khansela"</string>
+    <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Indawo yosizo lomlayezo"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Qinisekisa"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Thinta inzwa yesigxivizo somunwe"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Isithonjana sezigxivizo zeminwe"</string>
-    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Isithonjana sohlelo lokusebenza"</string>
-    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Indawo yosizo lomlayezo"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Kufunwa wena…"</string>
+    <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Isithonjana sobuso"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Inkinobho evumelekile yokusondeza"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Sondeza kancane esikrinini esikhudlwana"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth ixhunyiwe"</string>
@@ -440,7 +442,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>
@@ -823,9 +825,11 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Isitoreji"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Ukubonisa"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Izinhlelo zokusebenza ezisheshayo"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Izinhlelo zokusebenza ezisheshayo azidingi ukufakwa."</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> esebenzayo"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"Uhlelo lokusebenza luvulwe ngaphndle kokufakwa."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Uhlelo lokusebenza luvulwe ngaphandle kokufakwa. Thepha ukuze ufunde kabanzi."</string>
     <string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string>
-    <string name="go_to_web" msgid="2650669128861626071">"Iya kusiphequluli"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Iya kuwebhu"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Idatha yeselula"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"I-Wi-Fi ivaliwe"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4920fb2..d1320a3 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -160,13 +160,13 @@
     <color name="smart_reply_button_background">#ffffffff</color>
     <color name="smart_reply_button_stroke">#ffdadce0</color>
 
-    <!-- Fingerprint dialog colors -->
-    <color name="fingerprint_dialog_bg_color">#ffffffff</color> <!-- 100% white -->
-    <color name="fingerprint_dialog_text_dark_color">#dd000000</color> <!-- 87% black -->
-    <color name="fingerprint_dialog_text_light_color">#89000000</color> <!-- 54% black -->
-    <color name="fingerprint_dialog_dim_color">#80000000</color> <!-- 50% black -->
-    <color name="fingerprint_dialog_error_color">#fff44336</color> <!-- red -->
-    <color name="fingerprint_dialog_fingerprint_color">#ff008577</color> <!-- teal -->
+    <!-- Biometric dialog colors -->
+    <color name="biometric_dialog_bg_color">#ffffffff</color> <!-- 100% white -->
+    <color name="biometric_dialog_text_dark_color">#dd000000</color> <!-- 87% black -->
+    <color name="biometric_dialog_text_light_color">#89000000</color> <!-- 54% black -->
+    <color name="biometric_dialog_dim_color">#80000000</color> <!-- 50% black -->
+    <color name="biometric_dialog_error_color">#fff44336</color> <!-- red -->
+    <color name="biometric_dialog_biometric_color">#ff008577</color> <!-- teal -->
 
     <!-- Logout button -->
     <color name="logout_button_bg_color">#ccffffff</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 11bd392..2fbf42f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -107,7 +107,7 @@
     <integer name="quick_settings_num_columns">3</integer>
 
     <!-- The number of rows in the QuickSettings -->
-    <integer name="quick_settings_num_rows">1</integer>
+    <integer name="quick_settings_max_rows">3</integer>
 
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
@@ -146,19 +146,29 @@
     <!-- Should "LTE"/"4G" be shown instead of "LTE+"/"4G+" when on NETWORK_TYPE_LTE_CA? -->
     <bool name="config_hideLtePlus">false</bool>
 
-    <!-- milliseconds before the heads up notification auto-dismisses. -->
+    <!-- The number of milliseconds before the heads up notification auto-dismisses. -->
     <integer name="heads_up_notification_decay">5000</integer>
 
-    <!-- milliseconds after a heads up notification is pushed back
+    <!-- The number of milliseconds after a heads up notification is pushed back
      before the app can interrupt again. -->
     <integer name="heads_up_default_snooze_length_ms">60000</integer>
 
     <!-- Minimum display time for a heads up notification, in milliseconds. -->
     <integer name="heads_up_notification_minimum_time">2000</integer>
 
-    <!-- milliseconds before the heads up notification accepts touches. -->
+    <!-- The number of milliseconds before the heads up notification accepts touches. -->
     <integer name="touch_acceptance_delay">700</integer>
 
+    <!-- The number of milliseconds before the ambient notification auto-dismisses. This will
+         override the default pulse length. -->
+    <integer name="ambient_notification_decay">6000</integer>
+
+    <!-- Minimum display time for a heads up notification, in milliseconds. -->
+    <integer name="ambient_notification_minimum_time">2000</integer>
+
+    <!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
+    <integer name="ambient_notification_extension_time">6000</integer>
+
     <!-- The duration in seconds to wait before the dismiss buttons are shown. -->
     <integer name="recents_task_bar_dismiss_delay_seconds">1000</integer>
 
@@ -498,4 +508,7 @@
 
     <!-- Allow dragging the PIP to a location to close it -->
     <bool name="config_pipEnableDismissDragToEdge">true</bool>
+
+    <!-- SystemUI Plugins that can be loaded on user builds. -->
+    <string-array name="config_pluginWhitelist" translatable="false" />
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c168d4e..ab7dec9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -645,12 +645,7 @@
     <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>
-    <dimen name="keyguard_indication_margin_bottom_ambient">16dp</dimen>
 
     <!-- The text size for battery level -->
     <dimen name="battery_level_text_size">12sp</dimen>
@@ -939,9 +934,8 @@
          burn-in on AOD. -->
     <dimen name="burn_in_prevention_offset_y">50dp</dimen>
 
-    <!-- The maximum offset in either direction that the charging indication moves vertically
-         to prevent burn-in on AOD. -->
-    <dimen name="charging_indication_burn_in_prevention_offset_y">5dp</dimen>
+    <!-- The maximum offset in either direction that icons move to prevent burn-in on AOD. -->
+    <dimen name="default_burn_in_prevention_offset">5dp</dimen>
 
     <dimen name="corner_size">8dp</dimen>
     <dimen name="top_padding">0dp</dimen>
@@ -982,10 +976,10 @@
          the regular notification, when we have remote input history texts present. -->
     <dimen name="remote_input_history_extra_height">60dp</dimen>
 
-    <!-- Fingerprint Dialog values -->
-    <dimen name="fingerprint_dialog_fp_icon_size">64dp</dimen>
-    <dimen name="fingerprint_dialog_animation_translation_offset">350dp</dimen>
-    <dimen name="fingerprint_dialog_corner_size">4dp</dimen>
+    <!-- Biometric Dialog values -->
+    <dimen name="biometric_dialog_biometric_icon_size">64dp</dimen>
+    <dimen name="biometric_dialog_corner_size">4dp</dimen>
+    <dimen name="biometric_dialog_animation_translation_offset">350dp</dimen>
 
     <!-- Wireless Charging Animation values -->
     <dimen name="wireless_charging_dots_radius_start">0dp</dimen>
diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml
index 87c4bbb..fd7a105 100644
--- a/packages/SystemUI/res/values/integers.xml
+++ b/packages/SystemUI/res/values/integers.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 <resources>
-    <integer name="fingerprint_dialog_text_gravity">8388611</integer> <!-- gravity start -->
+    <integer name="biometric_dialog_text_gravity">8388611</integer> <!-- gravity start -->
 
     <!-- Action footer width used for layout_width to indicate WRAP_CONTENT (along with a weight of
          0) as we can allow the carrier text to stretch as far as needed in the QS footer. -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 36f97cd..e1c71fa 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -257,14 +257,20 @@
     <!-- Button name for "Cancel". [CHAR LIMIT=NONE] -->
     <string name="cancel">Cancel</string>
 
+    <!-- Content description for the error/help message are when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_biometric_dialog_help_area">Help message area</string>
+    <!-- Message shown when a biometric is authenticated, asking the user to confirm authentication [CHAR LIMIT=30] -->
+    <string name="biometric_dialog_confirm">Confirm</string>
+
     <!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
     <string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
     <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_fingerprint_dialog_fingerprint_icon">Fingerprint icon</string>
-    <!-- Content description of the application icon when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_fingerprint_dialog_app_icon">Application icon</string>
-    <!-- Content description for the error/help message are when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_fingerprint_dialog_help_area">Help message area</string>
+
+    <!-- Message shown when the system-provided face dialog is shown, asking for authentication [CHAR LIMIT=30] -->
+    <string name="face_dialog_looking_for_face">Looking for you\u2026</string>
+    <!-- Content description of the face icon when the system-provided face dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_face_dialog_face_icon">Face icon</string>
 
     <!-- Content description of the compatibility zoom button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_compatibility_zoom_button">Compatibility zoom button.</string>
@@ -1075,7 +1081,7 @@
     <string name="clear_all_notifications_text">Clear all</string>
 
     <!-- The text for the manage notifications link. [CHAR LIMIT=40] -->
-    <string name="manage_notifications_text">Manage notifications</string>
+    <string name="manage_notifications_text">Manage</string>
 
     <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
     <string name="dnd_suppressing_shade_text">Notifications paused by Do Not Disturb</string>
@@ -2132,14 +2138,23 @@
     <!-- App label of the instant apps notification [CHAR LIMIT=60] -->
     <string name="instant_apps">Instant Apps</string>
 
-    <!-- Message of the instant apps notification indicating they don't need install [CHAR LIMIT=NONE] -->
-    <string name="instant_apps_message">Instant apps don\'t require installation.</string>
+    <!-- Title of notification indicating that an instant app is running. [CHAR LIMIT=60] -->
+    <string name="instant_apps_title"><xliff:g id="app" example="Gmail">%1$s</xliff:g> running</string>
+
+    <!-- Message of the instant apps notification indicating they don't need install. [CHAR LIMIT=NONE] -->
+    <string name="instant_apps_message">App opened without being installed.</string>
+
+    <!-- Message of the instant apps notification indicating they don't need install, plus a link to more information. [CHAR LIMIT=NONE] -->
+    <string name="instant_apps_message_with_help">App opened without being installed. Tap to learn more.</string>
+
+    <!-- URL of the webpage that explains instant apps. -->
+    <string name="instant_apps_help_url" translatable="false"></string>
 
     <!-- Action label for launching app info on the specified app [CHAR LIMIT=20] -->
     <string name="app_info">App info</string>
 
     <!-- Action label for switching to a browser for an instant app [CHAR LIMIT=20] -->
-    <string name="go_to_web">Go to browser</string>
+    <string name="go_to_web">Go to web</string>
 
     <!-- Quick settings tile for toggling mobile data [CHAR LIMIT=20] -->
     <string name="mobile_data">Mobile data</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 710b5f7..31a538c 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -20,7 +20,11 @@
         "src/**/I*.aidl",
     ],
 
-    // Enforce that the library is build agains java 7 so that there are
+    static_libs: [
+        "PluginCoreLib"
+    ],
+
+    // 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
new file mode 100644
index 0000000..c6a086d
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java
@@ -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.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Looper;
+
+/**
+ * Provides necessary components for initializing {@link PluginManagerImpl}.
+ */
+public interface PluginInitializer {
+
+    Looper getBgLooper();
+
+    /**
+     * This Runnable is run on the bg looper during initialization of {@link PluginManagerImpl}.
+     */
+    @Nullable Runnable getBgInitCallback();
+
+    String[] getWhitelistedPlugins(Context context);
+
+    PluginEnabler getPluginEnabler(Context context);
+}
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
new file mode 100644
index 0000000..8cc6091
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.app.Notification;
+import android.app.Notification.Action;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.LayoutInflater;
+
+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.PluginFragment;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class PluginInstanceManager<T extends Plugin> {
+
+    private static final boolean DEBUG = false;
+
+    private static final String TAG = "PluginInstanceManager";
+    public static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
+
+    private final Context mContext;
+    private final PluginListener<T> mListener;
+    private final String mAction;
+    private final boolean mAllowMultiple;
+    private final VersionInfo mVersion;
+
+    @VisibleForTesting
+    final MainHandler mMainHandler;
+    @VisibleForTesting
+    final PluginHandler mPluginHandler;
+    private final boolean isDebuggable;
+    private final PackageManager mPm;
+    private final PluginManagerImpl mManager;
+    private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>();
+
+    PluginInstanceManager(Context context, String action, PluginListener<T> listener,
+            boolean allowMultiple, Looper looper, VersionInfo version, PluginManagerImpl manager) {
+        this(context, context.getPackageManager(), action, listener, allowMultiple, looper, version,
+                manager, Build.IS_DEBUGGABLE, manager.getWhitelistedPlugins());
+    }
+
+    @VisibleForTesting
+    PluginInstanceManager(Context context, PackageManager pm, String action,
+            PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version,
+            PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist) {
+        mMainHandler = new MainHandler(Looper.getMainLooper());
+        mPluginHandler = new PluginHandler(looper);
+        mManager = manager;
+        mContext = context;
+        mPm = pm;
+        mAction = action;
+        mListener = listener;
+        mAllowMultiple = allowMultiple;
+        mVersion = version;
+        mWhitelistedPlugins.addAll(Arrays.asList(pluginWhitelist));
+        isDebuggable = debuggable;
+    }
+
+    public PluginInfo<T> getPlugin() {
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new RuntimeException("Must be called from UI thread");
+        }
+        mPluginHandler.handleQueryPlugins(null /* All packages */);
+        if (mPluginHandler.mPlugins.size() > 0) {
+            mMainHandler.removeMessages(MainHandler.PLUGIN_CONNECTED);
+            PluginInfo<T> info = mPluginHandler.mPlugins.get(0);
+            PluginPrefs.setHasPlugins(mContext);
+            info.mPlugin.onCreate(mContext, info.mPluginContext);
+            return info;
+        }
+        return null;
+    }
+
+    public void loadAll() {
+        if (DEBUG) Log.d(TAG, "startListening");
+        mPluginHandler.sendEmptyMessage(PluginHandler.QUERY_ALL);
+    }
+
+    public void destroy() {
+        if (DEBUG) Log.d(TAG, "stopListening");
+        ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
+        for (PluginInfo plugin : plugins) {
+            mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED,
+                    plugin.mPlugin).sendToTarget();
+        }
+    }
+
+    public void onPackageRemoved(String pkg) {
+        mPluginHandler.obtainMessage(PluginHandler.REMOVE_PKG, pkg).sendToTarget();
+    }
+
+    public void onPackageChange(String pkg) {
+        mPluginHandler.obtainMessage(PluginHandler.REMOVE_PKG, pkg).sendToTarget();
+        mPluginHandler.obtainMessage(PluginHandler.QUERY_PKG, pkg).sendToTarget();
+    }
+
+    public boolean checkAndDisable(String className) {
+        boolean disableAny = false;
+        ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
+        for (PluginInfo info : plugins) {
+            if (className.startsWith(info.mPackage)) {
+                disable(info);
+                disableAny = true;
+            }
+        }
+        return disableAny;
+    }
+
+    public boolean disableAll() {
+        ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
+        for (int i = 0; i < plugins.size(); i++) {
+            disable(plugins.get(i));
+        }
+        return plugins.size() != 0;
+    }
+
+    private void disable(PluginInfo info) {
+        // Live by the sword, die by the sword.
+        // Misbehaving plugins get disabled and won't come back until uninstall/reinstall.
+
+        // If a plugin is detected in the stack of a crash then this will be called for that
+        // 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);
+        mManager.getPluginEnabler().setEnabled(new ComponentName(info.mPackage, info.mClass),
+                false);
+    }
+
+    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
+        ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
+        for (PluginInfo info : plugins) {
+            if (info.mPlugin.getClass().getName().equals(p.getClass().getName())) {
+                return info.mVersion != null && info.mVersion.hasClass(cls);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s@%s (action=%s)",
+                getClass().getSimpleName(), hashCode(), mAction);
+    }
+
+    private class MainHandler extends Handler {
+        private static final int PLUGIN_CONNECTED = 1;
+        private static final int PLUGIN_DISCONNECTED = 2;
+
+        public MainHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case PLUGIN_CONNECTED:
+                    if (DEBUG) Log.d(TAG, "onPluginConnected");
+                    PluginPrefs.setHasPlugins(mContext);
+                    PluginInfo<T> info = (PluginInfo<T>) msg.obj;
+                    mManager.handleWtfs();
+                    if (!(msg.obj instanceof PluginFragment)) {
+                        // Only call onDestroy for plugins that aren't fragments, as fragments
+                        // will get the onCreate as part of the fragment lifecycle.
+                        info.mPlugin.onCreate(mContext, info.mPluginContext);
+                    }
+                    mListener.onPluginConnected(info.mPlugin, info.mPluginContext);
+                    break;
+                case PLUGIN_DISCONNECTED:
+                    if (DEBUG) Log.d(TAG, "onPluginDisconnected");
+                    mListener.onPluginDisconnected((T) msg.obj);
+                    if (!(msg.obj instanceof PluginFragment)) {
+                        // Only call onDestroy for plugins that aren't fragments, as fragments
+                        // will get the onDestroy as part of the fragment lifecycle.
+                        ((T) msg.obj).onDestroy();
+                    }
+                    break;
+                default:
+                    super.handleMessage(msg);
+                    break;
+            }
+        }
+    }
+
+    private class PluginHandler extends Handler {
+        private static final int QUERY_ALL = 1;
+        private static final int QUERY_PKG = 2;
+        private static final int REMOVE_PKG = 3;
+
+        private final ArrayList<PluginInfo<T>> mPlugins = new ArrayList<>();
+
+        public PluginHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case QUERY_ALL:
+                    if (DEBUG) Log.d(TAG, "queryAll " + mAction);
+                    for (int i = mPlugins.size() - 1; i >= 0; i--) {
+                        PluginInfo<T> plugin = mPlugins.get(i);
+                        mListener.onPluginDisconnected(plugin.mPlugin);
+                        if (!(plugin.mPlugin instanceof PluginFragment)) {
+                            // Only call onDestroy for plugins that aren't fragments, as fragments
+                            // will get the onDestroy as part of the fragment lifecycle.
+                            plugin.mPlugin.onDestroy();
+                        }
+                    }
+                    mPlugins.clear();
+                    handleQueryPlugins(null);
+                    break;
+                case REMOVE_PKG:
+                    String pkg = (String) msg.obj;
+                    for (int i = mPlugins.size() - 1; i >= 0; i--) {
+                        final PluginInfo<T> plugin = mPlugins.get(i);
+                        if (plugin.mPackage.equals(pkg)) {
+                            mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED,
+                                    plugin.mPlugin).sendToTarget();
+                            mPlugins.remove(i);
+                        }
+                    }
+                    break;
+                case QUERY_PKG:
+                    String p = (String) msg.obj;
+                    if (DEBUG) Log.d(TAG, "queryPkg " + p + " " + mAction);
+                    if (mAllowMultiple || (mPlugins.size() == 0)) {
+                        handleQueryPlugins(p);
+                    } else {
+                        if (DEBUG) Log.d(TAG, "Too many of " + mAction);
+                    }
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+
+        private void handleQueryPlugins(String pkgName) {
+            // This isn't actually a service and shouldn't ever be started, but is
+            // a convenient PM based way to manage our plugins.
+            Intent intent = new Intent(mAction);
+            if (pkgName != null) {
+                intent.setPackage(pkgName);
+            }
+            List<ResolveInfo> result = mPm.queryIntentServices(intent, 0);
+            if (DEBUG) Log.d(TAG, "Found " + result.size() + " plugins");
+            if (result.size() > 1 && !mAllowMultiple) {
+                // TODO: Show warning.
+                Log.w(TAG, "Multiple plugins found for " + mAction);
+                return;
+            }
+            for (ResolveInfo info : result) {
+                ComponentName name = new ComponentName(info.serviceInfo.packageName,
+                        info.serviceInfo.name);
+                PluginInfo<T> t = handleLoadPlugin(name);
+                if (t == null) continue;
+                mMainHandler.obtainMessage(mMainHandler.PLUGIN_CONNECTED, t).sendToTarget();
+                mPlugins.add(t);
+            }
+        }
+
+        protected PluginInfo<T> handleLoadPlugin(ComponentName component) {
+            // This was already checked, but do it again here to make extra extra sure, we don't
+            // use these on production builds.
+            if (!isDebuggable && !mWhitelistedPlugins.contains(component.getPackageName())) {
+                // Never ever ever allow these on production builds, they are only for prototyping.
+                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 {
+                ApplicationInfo info = mPm.getApplicationInfo(pkg, 0);
+                // TODO: This probably isn't needed given that we don't have IGNORE_SECURITY on
+                if (mPm.checkPermission(PLUGIN_PERMISSION, pkg)
+                        != PackageManager.PERMISSION_GRANTED) {
+                    Log.d(TAG, "Plugin doesn't have permission: " + pkg);
+                    return null;
+                }
+                // Create our own ClassLoader so we can use our own code as the parent.
+                ClassLoader classLoader = mManager.getClassLoader(info.sourceDir, info.packageName);
+                Context pluginContext = new PluginContextWrapper(
+                        mContext.createApplicationContext(info, 0), classLoader);
+                Class<?> pluginClass = Class.forName(cls, true, classLoader);
+                // TODO: Only create the plugin before version check if we need it for
+                // legacy version check.
+                T plugin = (T) pluginClass.newInstance();
+                try {
+                    VersionInfo version = checkVersion(pluginClass, plugin, mVersion);
+                    if (DEBUG) Log.d(TAG, "createPlugin");
+                    return new PluginInfo(pkg, cls, plugin, pluginContext, version);
+                } catch (InvalidVersionException e) {
+                    final int icon = mContext.getResources().getIdentifier("tuner", "drawable",
+                            mContext.getPackageName());
+                    final int color = Resources.getSystem().getIdentifier(
+                            "system_notification_accent_color", "color", "android");
+                    final Notification.Builder nb = new Notification.Builder(mContext,
+                            PluginManager.NOTIFICATION_CHANNEL_ID)
+                                    .setStyle(new Notification.BigTextStyle())
+                                    .setSmallIcon(icon)
+                                    .setWhen(0)
+                                    .setShowWhen(false)
+                                    .setVisibility(Notification.VISIBILITY_PUBLIC)
+                                    .setColor(mContext.getColor(color));
+                    String label = cls;
+                    try {
+                        label = mPm.getServiceInfo(component, 0).loadLabel(mPm).toString();
+                    } catch (NameNotFoundException e2) {
+                    }
+                    if (!e.isTooNew()) {
+                        // Localization not required as this will never ever appear in a user build.
+                        nb.setContentTitle("Plugin \"" + label + "\" is too old")
+                                .setContentText("Contact plugin developer to get an updated"
+                                        + " version.\n" + e.getMessage());
+                    } else {
+                        // Localization not required as this will never ever appear in a user build.
+                        nb.setContentTitle("Plugin \"" + label + "\" is too new")
+                                .setContentText("Check to see if an OTA is available.\n"
+                                        + e.getMessage());
+                    }
+                    Intent i = new Intent(PluginManagerImpl.DISABLE_PLUGIN).setData(
+                            Uri.parse("package://" + component.flattenToString()));
+                    PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
+                    nb.addAction(new Action.Builder(null, "Disable plugin", pi).build());
+                    mContext.getSystemService(NotificationManager.class)
+                            .notifyAsUser(cls, SystemMessage.NOTE_PLUGIN, nb.build(),
+                                    UserHandle.ALL);
+                    // TODO: Warn user.
+                    Log.w(TAG, "Plugin has invalid interface version " + plugin.getVersion()
+                            + ", expected " + mVersion);
+                    return null;
+                }
+            } catch (Throwable e) {
+                Log.w(TAG, "Couldn't load plugin: " + pkg, e);
+                return null;
+            }
+        }
+
+        private VersionInfo checkVersion(Class<?> pluginClass, T plugin, VersionInfo version)
+                throws InvalidVersionException {
+            VersionInfo pv = new VersionInfo().addClass(pluginClass);
+            if (pv.hasVersionInfo()) {
+                version.checkVersion(pv);
+            } else {
+                int fallbackVersion = plugin.getVersion();
+                if (fallbackVersion != version.getDefaultVersion()) {
+                    throw new InvalidVersionException("Invalid legacy version", false);
+                }
+                return null;
+            }
+            return pv;
+        }
+    }
+
+    public static class PluginContextWrapper extends ContextWrapper {
+        private final ClassLoader mClassLoader;
+        private LayoutInflater mInflater;
+
+        public PluginContextWrapper(Context base, ClassLoader classLoader) {
+            super(base);
+            mClassLoader = classLoader;
+        }
+
+        @Override
+        public ClassLoader getClassLoader() {
+            return mClassLoader;
+        }
+
+        @Override
+        public Object getSystemService(String name) {
+            if (LAYOUT_INFLATER_SERVICE.equals(name)) {
+                if (mInflater == null) {
+                    mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
+                }
+                return mInflater;
+            }
+            return getBaseContext().getSystemService(name);
+        }
+    }
+
+    static class PluginInfo<T> {
+        private final Context mPluginContext;
+        private final VersionInfo mVersion;
+        private String mClass;
+        T mPlugin;
+        String mPackage;
+
+        public PluginInfo(String pkg, String cls, T plugin, Context pluginContext,
+                VersionInfo info) {
+            mPlugin = plugin;
+            mClass = cls;
+            mPackage = pkg;
+            mPluginContext = pluginContext;
+            mVersion = info;
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java
new file mode 100644
index 0000000..208f4fe
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.text.TextUtils;
+
+import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+public interface PluginManager {
+
+    String PLUGIN_CHANGED = "com.android.systemui.action.PLUGIN_CHANGED";
+
+    // must be one of the channels created in NotificationChannels.java
+    String NOTIFICATION_CHANNEL_ID = "ALR";
+
+    <T extends Plugin> T getOneShotPlugin(Class<T> cls);
+    <T extends Plugin> T getOneShotPlugin(String action, Class<?> cls);
+
+    <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls);
+    <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls,
+            boolean allowMultiple);
+    <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+            Class<?> cls);
+    <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+            Class cls, boolean allowMultiple);
+
+    void removePluginListener(PluginListener<?> listener);
+
+    <T> boolean dependsOn(Plugin p, Class<T> cls);
+
+    class Helper {
+        public static <P> String getAction(Class<P> cls) {
+            ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class);
+            if (info == null) {
+                throw new RuntimeException(cls + " doesn't provide an interface");
+            }
+            if (TextUtils.isEmpty(info.action())) {
+                throw new RuntimeException(cls + " doesn't provide an action");
+            }
+            return info.action();
+        }
+    }
+
+}
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
new file mode 100644
index 0000000..a54e08e
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.app.Notification;
+import android.app.Notification.Action;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import android.widget.Toast;
+
+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 dalvik.system.PathClassLoader;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.Arrays;
+import java.util.Map;
+/**
+ * @see Plugin
+ */
+public class PluginManagerImpl extends BroadcastReceiver implements PluginManager {
+
+    private static final String TAG = PluginManagerImpl.class.getSimpleName();
+    static final String DISABLE_PLUGIN = "com.android.systemui.action.DISABLE_PLUGIN";
+
+    private static PluginManager sInstance;
+
+    private final ArrayMap<PluginListener<?>, PluginInstanceManager> mPluginMap
+            = new ArrayMap<>();
+    private final Map<String, ClassLoader> mClassLoaders = new ArrayMap<>();
+    private final ArraySet<String> mOneShotPackages = new ArraySet<>();
+    private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>();
+    private final Context mContext;
+    private final PluginInstanceManagerFactory mFactory;
+    private final boolean isDebuggable;
+    private final PluginPrefs mPluginPrefs;
+    private final PluginEnabler mPluginEnabler;
+    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,
+                Thread.getUncaughtExceptionPreHandler(), initializer);
+    }
+
+    @VisibleForTesting
+    PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable,
+            UncaughtExceptionHandler defaultHandler, 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);
+
+        PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler(
+                defaultHandler);
+        Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
+
+        Runnable bgRunnable = initializer.getBgInitCallback();
+        if (bgRunnable != null) {
+            new Handler(mLooper).post(bgRunnable);
+        }
+    }
+
+    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) {
+            throw new RuntimeException(cls + " doesn't provide an interface");
+        }
+        if (TextUtils.isEmpty(info.action())) {
+            throw new RuntimeException(cls + " doesn't provide an action");
+        }
+        return getOneShotPlugin(info.action(), cls);
+    }
+
+    public <T extends Plugin> T getOneShotPlugin(String action, Class<?> cls) {
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new RuntimeException("Must be called from UI thread");
+        }
+        // Passing null causes compiler to complain about incompatible (generic) types.
+        PluginListener<Plugin> dummy = null;
+        PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, dummy,
+                false, mLooper, cls, this);
+        mPluginPrefs.addAction(action);
+        PluginInfo<T> info = p.getPlugin();
+        if (info != null) {
+            mOneShotPackages.add(info.mPackage);
+            mHasOneShot = true;
+            startListening();
+            return info.mPlugin;
+        }
+        return null;
+    }
+
+    public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls) {
+        addPluginListener(listener, cls, false);
+    }
+
+    public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls,
+            boolean allowMultiple) {
+        addPluginListener(PluginManager.Helper.getAction(cls), listener, cls, allowMultiple);
+    }
+
+    public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+            Class<?> cls) {
+        addPluginListener(action, listener, cls, false);
+    }
+
+    public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+            Class cls, boolean allowMultiple) {
+        mPluginPrefs.addAction(action);
+        PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener,
+                allowMultiple, mLooper, cls, this);
+        p.loadAll();
+        mPluginMap.put(listener, p);
+        startListening();
+    }
+
+    public void removePluginListener(PluginListener<?> listener) {
+        if (!mPluginMap.containsKey(listener)) return;
+        mPluginMap.remove(listener).destroy();
+        if (mPluginMap.size() == 0) {
+            stopListening();
+        }
+    }
+
+    private void startListening() {
+        if (mListening) return;
+        mListening = true;
+        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(PLUGIN_CHANGED);
+        filter.addAction(DISABLE_PLUGIN);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(this, filter);
+        filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
+        mContext.registerReceiver(this, filter);
+    }
+
+    private void stopListening() {
+        // Never stop listening if a one-shot is present.
+        if (!mListening || mHasOneShot) return;
+        mListening = false;
+        mContext.unregisterReceiver(this);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+            for (PluginInstanceManager manager : mPluginMap.values()) {
+                manager.loadAll();
+            }
+        } else if (DISABLE_PLUGIN.equals(intent.getAction())) {
+            Uri uri = intent.getData();
+            ComponentName component = ComponentName.unflattenFromString(
+                    uri.toString().substring(10));
+            getPluginEnabler().setEnabled(component, false);
+            mContext.getSystemService(NotificationManager.class).cancel(component.getClassName(),
+                    SystemMessage.NOTE_PLUGIN);
+        } else {
+            Uri data = intent.getData();
+            String pkg = data.getEncodedSchemeSpecificPart();
+            if (mOneShotPackages.contains(pkg)) {
+                int icon = mContext.getResources().getIdentifier("tuner", "drawable",
+                        mContext.getPackageName());
+                int color = Resources.getSystem().getIdentifier(
+                        "system_notification_accent_color", "color", "android");
+                String label = pkg;
+                try {
+                    PackageManager pm = mContext.getPackageManager();
+                    label = pm.getApplicationInfo(pkg, 0).loadLabel(pm).toString();
+                } catch (NameNotFoundException e) {
+                }
+                // Localization not required as this will never ever appear in a user build.
+                final Notification.Builder nb =
+                        new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+                                .setSmallIcon(icon)
+                                .setWhen(0)
+                                .setShowWhen(false)
+                                .setPriority(Notification.PRIORITY_MAX)
+                                .setVisibility(Notification.VISIBILITY_PUBLIC)
+                                .setColor(mContext.getColor(color))
+                                .setContentTitle("Plugin \"" + label + "\" has updated")
+                                .setContentText("Restart SysUI for changes to take effect.");
+                Intent i = new Intent("com.android.systemui.action.RESTART").setData(
+                            Uri.parse("package://" + pkg));
+                PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
+                nb.addAction(new Action.Builder(null, "Restart SysUI", pi).build());
+                mContext.getSystemService(NotificationManager.class).notifyAsUser(pkg,
+                        SystemMessage.NOTE_PLUGIN, nb.build(), UserHandle.ALL);
+            }
+            if (clearClassLoader(pkg)) {
+                Toast.makeText(mContext, "Reloading " + pkg, Toast.LENGTH_LONG).show();
+            }
+            if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                for (PluginInstanceManager manager : mPluginMap.values()) {
+                    manager.onPackageChange(pkg);
+                }
+            } else {
+                for (PluginInstanceManager manager : mPluginMap.values()) {
+                    manager.onPackageRemoved(pkg);
+                }
+            }
+        }
+    }
+
+    public ClassLoader getClassLoader(String sourceDir, String pkg) {
+        if (!isDebuggable && !mWhitelistedPlugins.contains(pkg)) {
+            Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:" + sourceDir +
+                    ", pkg: " + pkg);
+            return null;
+        }
+        if (mClassLoaders.containsKey(pkg)) {
+            return mClassLoaders.get(pkg);
+        }
+        ClassLoader classLoader = new PathClassLoader(sourceDir, getParentClassLoader());
+        mClassLoaders.put(pkg, classLoader);
+        return classLoader;
+    }
+
+    private boolean clearClassLoader(String pkg) {
+        return mClassLoaders.remove(pkg) != null;
+    }
+
+    ClassLoader getParentClassLoader() {
+        if (mParentClassLoader == null) {
+            // Lazily load this so it doesn't have any effect on devices without plugins.
+            mParentClassLoader = new ClassLoaderFilter(getClass().getClassLoader(),
+                    "com.android.systemui.plugin");
+        }
+        return mParentClassLoader;
+    }
+
+    public Context getContext(ApplicationInfo info, String pkg) throws NameNotFoundException {
+        ClassLoader classLoader = getClassLoader(info.sourceDir, pkg);
+        return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
+    }
+
+    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
+        for (int i = 0; i < mPluginMap.size(); i++) {
+            if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    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);
+                }
+            });
+        }
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println(String.format("  plugin map (%d):", mPluginMap.size()));
+        for (PluginListener listener: mPluginMap.keySet()) {
+            pw.println(String.format("    %s -> %s",
+                    listener, mPluginMap.get(listener)));
+        }
+    }
+
+    @VisibleForTesting
+    public static class PluginInstanceManagerFactory {
+        public <T extends Plugin> PluginInstanceManager createPluginInstanceManager(Context context,
+                String action, PluginListener<T> listener, boolean allowMultiple, Looper looper,
+                Class<?> cls, PluginManagerImpl manager) {
+            return new PluginInstanceManager(context, action, listener, allowMultiple, looper,
+                    new VersionInfo().addClass(cls), manager);
+        }
+    }
+
+    // This allows plugins to include any libraries or copied code they want by only including
+    // classes from the plugin library.
+    private static class ClassLoaderFilter extends ClassLoader {
+        private final String mPackage;
+        private final ClassLoader mBase;
+
+        public ClassLoaderFilter(ClassLoader base, String pkg) {
+            super(ClassLoader.getSystemClassLoader());
+            mBase = base;
+            mPackage = pkg;
+        }
+
+        @Override
+        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            if (!name.startsWith(mPackage)) super.loadClass(name, resolve);
+            return mBase.loadClass(name);
+        }
+    }
+
+    private class PluginExceptionHandler implements UncaughtExceptionHandler {
+        private final UncaughtExceptionHandler mHandler;
+
+        private PluginExceptionHandler(UncaughtExceptionHandler handler) {
+            mHandler = handler;
+        }
+
+        @Override
+        public void uncaughtException(Thread thread, Throwable throwable) {
+            if (SystemProperties.getBoolean("plugin.debugging", false)) {
+                mHandler.uncaughtException(thread, throwable);
+                return;
+            }
+            // Search for and disable plugins that may have been involved in this crash.
+            boolean disabledAny = checkStack(throwable);
+            if (!disabledAny) {
+                // We couldn't find any plugins involved in this crash, just to be safe
+                // disable all the plugins, so we can be sure that SysUI is running as
+                // best as possible.
+                for (PluginInstanceManager manager : mPluginMap.values()) {
+                    disabledAny |= manager.disableAll();
+                }
+            }
+            if (disabledAny) {
+                throwable = new CrashWhilePluginActiveException(throwable);
+            }
+
+            // Run the normal exception handler so we can crash and cleanup our state.
+            mHandler.uncaughtException(thread, throwable);
+        }
+
+        private boolean checkStack(Throwable throwable) {
+            if (throwable == null) return false;
+            boolean disabledAny = false;
+            for (StackTraceElement element : throwable.getStackTrace()) {
+                for (PluginInstanceManager manager : mPluginMap.values()) {
+                    disabledAny |= manager.checkAndDisable(element.getClassName());
+                }
+            }
+            return disabledAny | checkStack(throwable.getCause());
+        }
+    }
+
+    private class CrashWhilePluginActiveException extends RuntimeException {
+        public CrashWhilePluginActiveException(Throwable throwable) {
+            super(throwable);
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java
new file mode 100644
index 0000000..c0c5d70
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.ArraySet;
+
+import java.util.Set;
+
+/**
+ * Storage for all plugin actions in SharedPreferences.
+ *
+ * This allows the list of actions that the Tuner needs to search for to be generated
+ * instead of hard coded.
+ */
+public class PluginPrefs {
+
+    private static final String PREFS = "plugin_prefs";
+
+    private static final String PLUGIN_ACTIONS = "actions";
+    private static final String HAS_PLUGINS = "plugins";
+
+    private final Set<String> mPluginActions;
+    private final SharedPreferences mSharedPrefs;
+
+    public PluginPrefs(Context context) {
+        mSharedPrefs = context.getSharedPreferences(PREFS, 0);
+        mPluginActions = new ArraySet<>(mSharedPrefs.getStringSet(PLUGIN_ACTIONS, null));
+    }
+
+    public Set<String> getPluginList() {
+        return mPluginActions;
+    }
+
+    public synchronized void addAction(String action) {
+        if (mPluginActions.add(action)){
+            mSharedPrefs.edit().putStringSet(PLUGIN_ACTIONS, mPluginActions).commit();
+        }
+    }
+
+    public static boolean hasPlugins(Context context) {
+        return context.getSharedPreferences(PREFS, 0).getBoolean(HAS_PLUGINS, false);
+    }
+
+    public static void setHasPlugins(Context context) {
+        context.getSharedPreferences(PREFS, 0).edit().putBoolean(HAS_PLUGINS, true).commit();
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/VersionInfo.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/VersionInfo.java
new file mode 100644
index 0000000..bb845cd
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/VersionInfo.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.util.ArrayMap;
+
+import com.android.systemui.plugins.annotations.Dependencies;
+import com.android.systemui.plugins.annotations.DependsOn;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+import com.android.systemui.plugins.annotations.Requirements;
+import com.android.systemui.plugins.annotations.Requires;
+
+import java.util.function.BiConsumer;
+
+public class VersionInfo {
+
+    private final ArrayMap<Class<?>, Version> mVersions = new ArrayMap<>();
+    private Class<?> mDefault;
+
+    public boolean hasVersionInfo() {
+        return !mVersions.isEmpty();
+    }
+
+    public int getDefaultVersion() {
+        return mVersions.get(mDefault).mVersion;
+    }
+
+    public VersionInfo addClass(Class<?> cls) {
+        if (mDefault == null) {
+            // The legacy default version is from the first class we add.
+            mDefault = cls;
+        }
+        addClass(cls, false);
+        return this;
+    }
+
+    private void addClass(Class<?> cls, boolean required) {
+        if (mVersions.containsKey(cls)) return;
+        ProvidesInterface provider = cls.getDeclaredAnnotation(ProvidesInterface.class);
+        if (provider != null) {
+            mVersions.put(cls, new Version(provider.version(), true));
+        }
+        Requires requires = cls.getDeclaredAnnotation(Requires.class);
+        if (requires != null) {
+            mVersions.put(requires.target(), new Version(requires.version(), required));
+        }
+        Requirements requirements = cls.getDeclaredAnnotation(Requirements.class);
+        if (requirements != null) {
+            for (Requires r : requirements.value()) {
+                mVersions.put(r.target(), new Version(r.version(), required));
+            }
+        }
+        DependsOn depends = cls.getDeclaredAnnotation(DependsOn.class);
+        if (depends != null) {
+            addClass(depends.target(), true);
+        }
+        Dependencies dependencies = cls.getDeclaredAnnotation(Dependencies.class);
+        if (dependencies != null) {
+            for (DependsOn d : dependencies.value()) {
+                addClass(d.target(), true);
+            }
+        }
+    }
+
+    public void checkVersion(VersionInfo plugin) throws InvalidVersionException {
+        final ArrayMap<Class<?>, Version> versions = new ArrayMap<>(mVersions);
+        plugin.mVersions.forEach(new BiConsumer<Class<?>, Version>() {
+            @Override
+            public void accept(Class<?> aClass, Version version) {
+                Version v = versions.remove(aClass);
+                if (v == null) {
+                    v = VersionInfo.this.createVersion(aClass);
+                }
+                if (v == null) {
+                    throw new InvalidVersionException(aClass.getSimpleName()
+                            + " does not provide an interface", false);
+                }
+                if (v.mVersion != version.mVersion) {
+                    throw new InvalidVersionException(aClass, v.mVersion < version.mVersion,
+                            v.mVersion,
+                            version.mVersion);
+                }
+            }
+        });
+        versions.forEach(new BiConsumer<Class<?>, Version>() {
+            @Override
+            public void accept(Class<?> aClass, Version version) {
+                if (version.mRequired) {
+                    throw new InvalidVersionException("Missing required dependency "
+                            + aClass.getSimpleName(), false);
+                }
+            }
+        });
+    }
+
+    private Version createVersion(Class<?> cls) {
+        ProvidesInterface provider = cls.getDeclaredAnnotation(ProvidesInterface.class);
+        if (provider != null) {
+            return new Version(provider.version(), false);
+        }
+        return null;
+    }
+
+    public <T> boolean hasClass(Class<T> cls) {
+        return mVersions.containsKey(cls);
+    }
+
+    public static class InvalidVersionException extends RuntimeException {
+        private final boolean mTooNew;
+
+        public InvalidVersionException(String str, boolean tooNew) {
+            super(str);
+            mTooNew = tooNew;
+        }
+
+        public InvalidVersionException(Class<?> cls, boolean tooNew, int expected, int actual) {
+            super(cls.getSimpleName() + " expected version " + expected + " but had " + actual);
+            mTooNew = tooNew;
+        }
+
+        public boolean isTooNew() {
+            return mTooNew;
+        }
+    }
+
+    private static class Version {
+
+        private final int mVersion;
+        private final boolean mRequired;
+
+        public Version(int version, boolean required) {
+            mVersion = version;
+            mRequired = required;
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java
index ab89043..e253360 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java
@@ -21,13 +21,11 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
+import android.graphics.Picture;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-import android.view.ThreadedRenderer;
 import android.view.View;
 
 import java.util.function.Consumer;
@@ -108,12 +106,10 @@
      *         null if we were unable to allocate a hardware bitmap.
      */
     public static Bitmap createHardwareBitmap(int width, int height, Consumer<Canvas> consumer) {
-        RenderNode node = RenderNode.create("RecentsTransition", null);
-        node.setLeftTopRightBottom(0, 0, width, height);
-        node.setClipToBounds(false);
-        DisplayListCanvas c = node.start(width, height);
-        consumer.accept(c);
-        node.end(c);
-        return ThreadedRenderer.createHardwareBitmap(node, width, height);
+        final Picture picture = new Picture();
+        final Canvas canvas = picture.beginRecording(width, height);
+        consumer.accept(canvas);
+        picture.endRecording();
+        return Bitmap.createBitmap(picture);
     }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index b04d047..c7910f9 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -342,6 +342,20 @@
     }
 
     /**
+     * Moves an already resumed task to the side of the screen to initiate split screen.
+     */
+    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
+            Rect initialBounds) {
+        try {
+            return ActivityTaskManager.getService().setTaskWindowingModeSplitScreenPrimary(taskId,
+                    createMode, true /* onTop */, false /* animate */, initialBounds,
+                    true /* showRecents */);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
      * Registers a task stack listener with the system.
      * This should be called on the main thread.
      */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
index 36fb3a7..7154f53 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
@@ -21,6 +21,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 
 import android.app.ActivityOptions;
+import android.content.Context;
+import android.os.Handler;
 
 /**
  * Wrapper around internal ActivityOptions creation.
@@ -43,4 +45,17 @@
             RemoteAnimationAdapterCompat remoteAnimationAdapter) {
         return ActivityOptions.makeRemoteAnimation(remoteAnimationAdapter.getWrapped());
     }
+
+    public static ActivityOptions makeCustomAnimation(Context context, int enterResId,
+            int exitResId, final Runnable callback, final Handler callbackHandler) {
+        return ActivityOptions.makeCustomAnimation(context, enterResId, exitResId, callbackHandler,
+                new ActivityOptions.OnAnimationStartedListener() {
+                    @Override
+                    public void onAnimationStarted() {
+                        if (callback != null) {
+                            callbackHandler.post(callback);
+                        }
+                    }
+                });
+    }
 }
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/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index d83b36d..3191d14 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -151,6 +151,25 @@
         }
     }
 
+    public void setPipVisibility(final boolean visible) {
+        try {
+            WindowManagerGlobal.getWindowManagerService().setPipVisibility(visible);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to reach window manager", e);
+        }
+    }
+
+    /**
+     * @return whether there is a soft nav bar.
+     */
+    public boolean hasSoftNavigationBar() {
+        try {
+            return WindowManagerGlobal.getWindowManagerService().hasNavigationBar();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     /**
      * @return The side of the screen where navigation bar is positioned.
      * @see #NAV_BAR_POS_RIGHT
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 5bbbc52..28eff46 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -14,7 +14,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 
 /**
  * Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 5ffdc7b..2daa33b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -377,6 +377,7 @@
 
     @Override
     public void onResume(int reason) {
+        displayDefaultSecurityMessage();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index b159b39..b8df3c06 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -342,12 +342,11 @@
                 case SimPuk:
                     // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
                     SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
-                    if (securityMode != SecurityMode.None
-                            || !mLockPatternUtils.isLockScreenDisabled(
+                    if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
                             KeyguardUpdateMonitor.getCurrentUser())) {
-                        showSecurityScreen(securityMode);
-                    } else {
                         finish = true;
+                    } else {
+                        showSecurityScreen(securityMode);
                     }
                     break;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ff6a1c9..c7685f8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -39,7 +39,6 @@
 import android.app.UserSwitchObserver;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
-import android.hardware.biometrics.BiometricSourceType;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -49,6 +48,9 @@
 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;
@@ -75,7 +77,6 @@
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IccCardConstants;
@@ -85,9 +86,8 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settingslib.WirelessUtils;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.google.android.collect.Lists;
 
 import java.io.FileDescriptor;
@@ -355,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
@@ -1120,7 +1132,7 @@
     private CancellationSignal mFingerprintCancelSignal;
     private CancellationSignal mFaceCancelSignal;
     private FingerprintManager mFpm;
-    private FaceManager mFaceAuthenticationManager;
+    private FaceManager mFaceManager;
 
     /**
      * When we receive a
@@ -1458,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);
@@ -1549,7 +1565,7 @@
                 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
                 shouldListenForFaceAssistant() || (mKeyguardOccluded && mIsDreaming))
                 && !mSwitchingUser && !isFaceDisabled(getCurrentUser())
-                && !mKeyguardGoingAway;
+                && !mKeyguardGoingAway && mFaceSettingEnabledForUser;
     }
 
 
@@ -1583,7 +1599,7 @@
                 mFaceCancelSignal.cancel();
             }
             mFaceCancelSignal = new CancellationSignal();
-            mFaceAuthenticationManager.authenticate(null, mFaceCancelSignal, 0,
+            mFaceManager.authenticate(null, mFaceCancelSignal, 0,
                     mFaceAuthenticationCallback, null);
             setFaceRunningState(BIOMETRIC_STATE_RUNNING);
         }
@@ -1595,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() {
@@ -2170,8 +2186,8 @@
         }
     }
 
-    private final SysUiTaskStackChangeListener
-            mTaskStackListener = new SysUiTaskStackChangeListener() {
+    private final TaskStackChangeListener
+            mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onTaskStackChangedBackground() {
             try {
@@ -2390,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 + ")");
@@ -2402,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/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index b2cf305..fe1fe1a 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -39,9 +39,10 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.PluginInitializerImpl;
 import com.android.systemui.plugins.PluginDependencyProvider;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.plugins.PluginManagerImpl;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManagerImpl;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
@@ -236,7 +237,7 @@
                 new DeviceProvisionedControllerImpl(mContext));
 
         mProviders.put(PluginManager.class, () ->
-                new PluginManagerImpl(mContext));
+                new PluginManagerImpl(mContext, new PluginInitializerImpl()));
 
         mProviders.put(AssistManager.class, () ->
                 new AssistManager(getDependency(DeviceProvisionedController.class), mContext));
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index bd2b7a5..d351c4f3 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -16,6 +16,15 @@
 
 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;
+
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -33,11 +42,7 @@
 import android.provider.Settings;
 import android.util.Log;
 import android.view.MotionEvent;
-
 import com.android.systemui.OverviewProxyService.OverviewProxyListener;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -46,17 +51,11 @@
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-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;
-
 /**
  * Class to send information from overview to launcher with a binder.
  */
@@ -91,6 +90,7 @@
     private boolean mIsEnabled;
     private int mCurrentBoundedUserId = -1;
     private float mBackButtonAlpha;
+    private MotionEvent mStatusBarGestureDownEvent;
 
     private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
 
@@ -113,6 +113,9 @@
         }
 
         public void onStatusBarMotionEvent(MotionEvent event) {
+            if (!verifyCaller("onStatusBarMotionEvent")) {
+                return;
+            }
             long token = Binder.clearCallingIdentity();
             try {
                 // TODO move this logic to message queue
@@ -120,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 {
@@ -133,7 +146,10 @@
             }
             long token = Binder.clearCallingIdentity();
             try {
-                EventBus.getDefault().post(new DockedFirstAnimationFrameEvent());
+                Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
+                if (divider != null) {
+                    divider.onDockedFirstAnimationFrame();
+                }
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -300,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;
@@ -314,8 +330,7 @@
                 getDefaultInteractionFlags());
 
         // Listen for the package update changes.
-        if (SystemServicesProxy.getInstance(context)
-                .isSystemUser(mDeviceProvisionedController.getCurrentUser())) {
+        if (mDeviceProvisionedController.getCurrentUser() == UserHandle.USER_SYSTEM) {
             updateEnabledState();
             mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
@@ -331,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/PluginInflateContainer.java b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
index ddd4833..f6ad626 100644
--- a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
@@ -21,7 +21,7 @@
 import android.view.View;
 
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.plugins.ViewProvider;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index f9dbf4a..fb343f9 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -22,27 +22,10 @@
 
 public interface RecentsComponent {
     void showRecentApps(boolean triggeredFromAltTab);
-    void showNextAffiliatedTask();
-    void showPrevAffiliatedTask();
 
     /**
      * Docks the top-most task and opens recents.
      */
-    boolean splitPrimaryTask(int dragMode, int stackCreateMode, Rect initialBounds,
+    boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
             int metricsDockAction);
-
-    /**
-     * Called during a drag-from-navbar-in gesture.
-     *
-     * @param distanceFromTop the distance of the current drag in gesture from the top of the
-     *                        screen
-     */
-    void onDraggingInRecents(float distanceFromTop);
-
-    /**
-     * Called when the gesture to drag in recents ended.
-     *
-     * @param velocity the velocity of the finger when releasing it in pixels per second
-     */
-    void onDraggingInRecentsEnded(float velocity);
 }
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 044cc5c..4d24d82 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,9 +207,11 @@
 
         mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
         mOverlay.setAlpha(0);
+        mOverlay.setAllowForceDark(false);
 
         mBottomOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
         mBottomOverlay.setAlpha(0);
+        mBottomOverlay.setAllowForceDark(false);
 
         updateViews();
 
@@ -537,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];
@@ -627,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();
@@ -711,32 +733,17 @@
 
         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);
-                    break;
+                    out.set(displayCutout.getBoundingRectTop());
                 case Gravity.LEFT:
-                    bounds.op(0, 0, displayCutout.getSafeInsetLeft(), Integer.MAX_VALUE,
-                            Region.Op.INTERSECT);
-                    break;
+                    out.set(displayCutout.getBoundingRectLeft());
                 case Gravity.BOTTOM:
-                    bounds.op(0, displayCutout.getSafeInsetTop() + 1, Integer.MAX_VALUE,
-                            Integer.MAX_VALUE, Region.Op.INTERSECT);
-                    break;
+                    out.set(displayCutout.getBoundingRectBottom());
                 case Gravity.RIGHT:
-                    bounds.op(displayCutout.getSafeInsetLeft() + 1, 0, Integer.MAX_VALUE,
-                            Integer.MAX_VALUE, Region.Op.INTERSECT);
-                    break;
+                    out.set(displayCutout.getBoundingRectRight());
             }
-            return bounds;
+            out.setEmpty();
         }
 
         private void localBounds(Rect out) {
@@ -769,7 +776,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/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index a3b5395..0215fda 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -61,13 +61,14 @@
     public static final float SWIPED_FAR_ENOUGH_SIZE_FRACTION = 0.6f;
     static final float MAX_SCROLL_SIZE_FRACTION = 0.3f;
 
+    protected final Handler mHandler;
+
     private float mMinSwipeProgress = 0f;
     private float mMaxSwipeProgress = 1f;
 
     private final FlingAnimationUtils mFlingAnimationUtils;
     private float mPagingTouchSlop;
     private final Callback mCallback;
-    private final Handler mHandler;
     private final int mSwipeDirection;
     private final VelocityTracker mVelocityTracker;
     private final FalsingManager mFalsingManager;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index b96a604..78053b2 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -34,7 +34,7 @@
 
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.util.NotificationChannels;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 04d72ce..258b6f6 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -30,6 +30,7 @@
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
@@ -137,6 +138,7 @@
         providers.put(NotificationGroupManager.class, NotificationGroupManager::new);
         providers.put(NotificationMediaManager.class, () -> new NotificationMediaManager(context));
         providers.put(NotificationGutsManager.class, () -> new NotificationGutsManager(context));
+        providers.put(AmbientPulseManager.class, () -> new AmbientPulseManager(context));
         providers.put(NotificationBlockingHelperManager.class,
                 () -> new NotificationBlockingHelperManager(context));
         providers.put(NotificationRemoteInputManager.class,
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index bb82a54..8e29841 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -28,8 +28,8 @@
 import java.io.PrintWriter;
 
 import com.android.internal.os.BinderInternal;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.plugins.PluginManagerImpl;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManagerImpl;
 
 public class SystemUIService extends Service {
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index 8fe577a..8fc4689 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.IBiometricPromptReceiver;
 import android.os.Bundle;
@@ -31,9 +32,12 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.CommandQueue;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Receives messages sent from AuthenticationClient and shows the appropriate biometric UI (e.g.
- * FingerprintDialogView).
+ * BiometricDialogView).
  */
 public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callbacks {
     private static final String TAG = "BiometricDialogImpl";
@@ -48,7 +52,8 @@
     private static final int MSG_USER_CANCELED = 7;
     private static final int MSG_BUTTON_POSITIVE = 8;
 
-    private FingerprintDialogView mDialogView;
+    private Map<Integer, BiometricDialogView> mDialogs; // BiometricAuthenticator type, view
+    private BiometricDialogView mCurrentDialog;
     private WindowManager mWindowManager;
     private IBiometricPromptReceiver mReceiver;
     private boolean mDialogShowing;
@@ -111,16 +116,25 @@
 
     @Override
     public void start() {
-        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
-            return;
+        final PackageManager pm = mContext.getPackageManager();
+        mDialogs = new HashMap<>();
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+            mDialogs.put(BiometricAuthenticator.TYPE_FACE, new FaceDialogView(mContext, mCallback));
         }
-        getComponent(CommandQueue.class).addCallbacks(this);
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mDialogView = new FingerprintDialogView(mContext, mCallback);
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+            mDialogs.put(BiometricAuthenticator.TYPE_FINGERPRINT,
+                    new FingerprintDialogView(mContext, mCallback));
+        }
+
+        if (!mDialogs.isEmpty()) {
+            getComponent(CommandQueue.class).addCallbacks(this);
+            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        }
     }
 
     @Override
-    public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type) {
+    public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type,
+            boolean requireConfirmation) {
         if (DEBUG) Log.d(TAG, "showBiometricDialog, type: " + type);
         // Remove these messages as they are part of the previous client
         mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
@@ -129,6 +143,8 @@
         SomeArgs args = SomeArgs.obtain();
         args.arg1 = bundle;
         args.arg2 = receiver;
+        args.argi1 = type;
+        args.arg3 = requireConfirmation;
         mHandler.obtainMessage(MSG_SHOW_DIALOG, args).sendToTarget();
     }
 
@@ -157,33 +173,41 @@
     }
 
     private void handleShowDialog(SomeArgs args) {
+        final int type = args.argi1;
+        mCurrentDialog = mDialogs.get(type);
+
         if (DEBUG) Log.d(TAG, "handleShowDialog, isAnimatingAway: "
-                + mDialogView.isAnimatingAway());
-        if (mDialogView.isAnimatingAway()) {
-            mDialogView.forceRemove();
+                + mCurrentDialog.isAnimatingAway() + " type: " + type);
+
+        if (mCurrentDialog.isAnimatingAway()) {
+            mCurrentDialog.forceRemove();
         } else if (mDialogShowing) {
             Log.w(TAG, "Dialog already showing");
             return;
         }
         mReceiver = (IBiometricPromptReceiver) args.arg2;
-        mDialogView.setBundle((Bundle)args.arg1);
-        mWindowManager.addView(mDialogView, mDialogView.getLayoutParams());
+        mCurrentDialog.setBundle((Bundle)args.arg1);
+        mCurrentDialog.setRequireConfirmation((boolean)args.arg3);
+        mWindowManager.addView(mCurrentDialog, mCurrentDialog.getLayoutParams());
         mDialogShowing = true;
     }
 
     private void handleBiometricAuthenticated() {
         if (DEBUG) Log.d(TAG, "handleBiometricAuthenticated");
 
-        // TODO: announce correct string depending on modality
-        mDialogView.announceForAccessibility(
-                mContext.getResources().getText(
-                        com.android.internal.R.string.fingerprint_authenticated));
-        handleHideDialog(false /* userCanceled */);
+        mCurrentDialog.announceForAccessibility(
+                mContext.getResources()
+                        .getText(mCurrentDialog.getAuthenticatedAccessibilityResourceId()));
+        if (mCurrentDialog.requiresConfirmation()) {
+            mCurrentDialog.showConfirmationButton();
+        } else {
+            handleHideDialog(false /* userCanceled */);
+        }
     }
 
     private void handleBiometricHelp(String message) {
         if (DEBUG) Log.d(TAG, "handleBiometricHelp: " + message);
-        mDialogView.showHelpMessage(message);
+        mCurrentDialog.showHelpMessage(message);
     }
 
     private void handleBiometricError(String error) {
@@ -192,7 +216,7 @@
             if (DEBUG) Log.d(TAG, "Dialog already dismissed");
             return;
         }
-        mDialogView.showErrorMessage(error);
+        mCurrentDialog.showErrorMessage(error);
     }
 
     private void handleHideDialog(boolean userCanceled) {
@@ -212,7 +236,7 @@
         }
         mReceiver = null;
         mDialogShowing = false;
-        mDialogView.startDismiss();
+        mCurrentDialog.startDismiss();
     }
 
     private void handleButtonNegative() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
new file mode 100644
index 0000000..7d77929
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.biometrics;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.hardware.biometrics.BiometricPrompt;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.animation.Interpolator;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+
+/**
+ * Abstract base class. Shows a dialog for BiometricPrompt.
+ */
+public abstract class BiometricDialogView extends LinearLayout {
+
+    private static final String TAG = "BiometricDialogView";
+
+    private static final int ANIMATION_DURATION_SHOW = 250; // ms
+    private static final int ANIMATION_DURATION_AWAY = 350; // ms
+
+    private static final int MSG_CLEAR_MESSAGE = 1;
+
+    protected static final int STATE_NONE = 0;
+    protected static final int STATE_AUTHENTICATING = 1;
+    protected static final int STATE_ERROR = 2;
+    protected static final int STATE_AUTHENTICATED = 3;
+
+    private final IBinder mWindowToken = new Binder();
+    private final Interpolator mLinearOutSlowIn;
+    private final WindowManager mWindowManager;
+    private final float mAnimationTranslationOffset;
+    private final int mErrorColor;
+    private final int mTextColor;
+    private final float mDisplayWidth;
+    private final DialogViewCallback mCallback;
+
+    private ViewGroup mLayout;
+    private final TextView mErrorText;
+    private Bundle mBundle;
+    private final LinearLayout mDialog;
+    private int mLastState;
+    private boolean mAnimatingAway;
+    private boolean mWasForceRemoved;
+    protected boolean mRequireConfirmation;
+
+    protected abstract void updateIcon(int lastState, int newState);
+    protected abstract int getHintStringResourceId();
+    protected abstract int getAuthenticatedAccessibilityResourceId();
+    protected abstract int getIconDescriptionResourceId();
+
+    private final Runnable mShowAnimationRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mLayout.animate()
+                    .alpha(1f)
+                    .setDuration(ANIMATION_DURATION_SHOW)
+                    .setInterpolator(mLinearOutSlowIn)
+                    .withLayer()
+                    .start();
+            mDialog.animate()
+                    .translationY(0)
+                    .setDuration(ANIMATION_DURATION_SHOW)
+                    .setInterpolator(mLinearOutSlowIn)
+                    .withLayer()
+                    .start();
+        }
+    };
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_CLEAR_MESSAGE:
+                    handleClearMessage();
+                    break;
+                default:
+                    Log.e(TAG, "Unhandled message: " + msg.what);
+                    break;
+            }
+        }
+    };
+
+    public BiometricDialogView(Context context, DialogViewCallback callback) {
+        super(context);
+        mCallback = callback;
+        mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        mAnimationTranslationOffset = getResources()
+                .getDimension(R.dimen.biometric_dialog_animation_translation_offset);
+        mErrorColor = Color.parseColor(
+                getResources().getString(R.color.biometric_dialog_error_color));
+        mTextColor = Color.parseColor(
+                getResources().getString(R.color.biometric_dialog_text_light_color));
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mWindowManager.getDefaultDisplay().getMetrics(metrics);
+        mDisplayWidth = metrics.widthPixels;
+
+        // Create the dialog
+        LayoutInflater factory = LayoutInflater.from(getContext());
+        mLayout = (ViewGroup) factory.inflate(R.layout.biometric_dialog, this, false);
+        addView(mLayout);
+
+        mDialog = mLayout.findViewById(R.id.dialog);
+
+        mErrorText = mLayout.findViewById(R.id.error);
+
+        mLayout.setOnKeyListener(new View.OnKeyListener() {
+            boolean downPressed = false;
+            @Override
+            public boolean onKey(View v, int keyCode, KeyEvent event) {
+                if (keyCode != KeyEvent.KEYCODE_BACK) {
+                    return false;
+                }
+                if (event.getAction() == KeyEvent.ACTION_DOWN && downPressed == false) {
+                    downPressed = true;
+                } else if (event.getAction() == KeyEvent.ACTION_DOWN) {
+                    downPressed = false;
+                } else if (event.getAction() == KeyEvent.ACTION_UP && downPressed == true) {
+                    downPressed = false;
+                    mCallback.onUserCanceled();
+                }
+                return true;
+            }
+        });
+
+        final View space = mLayout.findViewById(R.id.space);
+        final View leftSpace = mLayout.findViewById(R.id.left_space);
+        final View rightSpace = mLayout.findViewById(R.id.right_space);
+        final Button negative = mLayout.findViewById(R.id.button2);
+        final Button positive = mLayout.findViewById(R.id.button1);
+        final ImageView icon = mLayout.findViewById(R.id.biometric_icon);
+
+        icon.setContentDescription(getResources().getString(getIconDescriptionResourceId()));
+        mErrorText.setText(getResources().getString(getHintStringResourceId()));
+
+        setDismissesDialog(space);
+        setDismissesDialog(leftSpace);
+        setDismissesDialog(rightSpace);
+
+        negative.setOnClickListener((View v) -> {
+            mCallback.onNegativePressed();
+        });
+
+        positive.setOnClickListener((View v) -> {
+            mCallback.onPositivePressed();
+        });
+
+        mLayout.setFocusableInTouchMode(true);
+        mLayout.requestFocus();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        final TextView title = mLayout.findViewById(R.id.title);
+        final TextView subtitle = mLayout.findViewById(R.id.subtitle);
+        final TextView description = mLayout.findViewById(R.id.description);
+        final Button negative = mLayout.findViewById(R.id.button2);
+        final Button positive = mLayout.findViewById(R.id.button1);
+
+        mDialog.getLayoutParams().width = (int) mDisplayWidth;
+
+        mLastState = STATE_NONE;
+        updateState(STATE_AUTHENTICATING);
+
+        CharSequence titleText = mBundle.getCharSequence(BiometricPrompt.KEY_TITLE);
+
+        title.setText(titleText);
+        title.setSelected(true);
+
+        positive.setVisibility(View.INVISIBLE);
+
+        final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
+        if (TextUtils.isEmpty(subtitleText)) {
+            subtitle.setVisibility(View.GONE);
+        } else {
+            subtitle.setVisibility(View.VISIBLE);
+            subtitle.setText(subtitleText);
+        }
+
+        final CharSequence descriptionText = mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
+        if (TextUtils.isEmpty(descriptionText)) {
+            description.setVisibility(View.GONE);
+        } else {
+            description.setVisibility(View.VISIBLE);
+            description.setText(descriptionText);
+        }
+
+        negative.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
+
+        if (!mWasForceRemoved) {
+            // Dim the background and slide the dialog up
+            mDialog.setTranslationY(mAnimationTranslationOffset);
+            mLayout.setAlpha(0f);
+            postOnAnimation(mShowAnimationRunnable);
+        } else {
+            // Show the dialog immediately
+            mLayout.animate().cancel();
+            mDialog.animate().cancel();
+            mDialog.setAlpha(1.0f);
+            mDialog.setTranslationY(0);
+            mLayout.setAlpha(1.0f);
+        }
+        mWasForceRemoved = false;
+    }
+
+    private void setDismissesDialog(View v) {
+        v.setClickable(true);
+        v.setOnTouchListener((View view, MotionEvent event) -> {
+            mCallback.onUserCanceled();
+            return true;
+        });
+    }
+
+    public void startDismiss() {
+        mAnimatingAway = true;
+
+        final Runnable endActionRunnable = new Runnable() {
+            @Override
+            public void run() {
+                mWindowManager.removeView(BiometricDialogView.this);
+                mAnimatingAway = false;
+            }
+        };
+
+        postOnAnimation(new Runnable() {
+            @Override
+            public void run() {
+                mLayout.animate()
+                        .alpha(0f)
+                        .setDuration(ANIMATION_DURATION_AWAY)
+                        .setInterpolator(mLinearOutSlowIn)
+                        .withLayer()
+                        .start();
+                mDialog.animate()
+                        .translationY(mAnimationTranslationOffset)
+                        .setDuration(ANIMATION_DURATION_AWAY)
+                        .setInterpolator(mLinearOutSlowIn)
+                        .withLayer()
+                        .withEndAction(endActionRunnable)
+                        .start();
+            }
+        });
+    }
+
+    /**
+     * Force remove the window, cancelling any animation that's happening. This should only be
+     * called if we want to quickly show the dialog again (e.g. on rotation). Calling this method
+     * will cause the dialog to show without an animation the next time it's attached.
+     */
+    public void forceRemove() {
+        mLayout.animate().cancel();
+        mDialog.animate().cancel();
+        mWindowManager.removeView(BiometricDialogView.this);
+        mAnimatingAway = false;
+        mWasForceRemoved = true;
+    }
+
+    public boolean isAnimatingAway() {
+        return mAnimatingAway;
+    }
+
+    public void setBundle(Bundle bundle) {
+        mBundle = bundle;
+    }
+
+    public void setRequireConfirmation(boolean requireConfirmation) {
+        mRequireConfirmation = requireConfirmation;
+    }
+
+    public boolean requiresConfirmation() {
+        return mRequireConfirmation;
+    }
+
+    public void showConfirmationButton() {
+        final Button positive = mLayout.findViewById(R.id.button1);
+        positive.setVisibility(View.VISIBLE);
+    }
+
+    public ViewGroup getLayout() {
+        return mLayout;
+    }
+
+    // Clears the temporary message and shows the help message.
+    private void handleClearMessage() {
+        updateState(STATE_AUTHENTICATING);
+        mErrorText.setText(getHintStringResourceId());
+        mErrorText.setTextColor(mTextColor);
+    }
+
+    // Shows an error/help message
+    private void showTemporaryMessage(String message) {
+        mHandler.removeMessages(MSG_CLEAR_MESSAGE);
+        updateState(STATE_ERROR);
+        mErrorText.setText(message);
+        mErrorText.setTextColor(mErrorColor);
+        mErrorText.setContentDescription(message);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_MESSAGE),
+                BiometricPrompt.HIDE_DIALOG_DELAY);
+    }
+
+    public void showHelpMessage(String message) {
+        showTemporaryMessage(message);
+    }
+
+    public void showErrorMessage(String error) {
+        showTemporaryMessage(error);
+        mCallback.onErrorShown();
+    }
+
+    private void updateState(int newState) {
+        updateIcon(mLastState, newState);
+        mLastState = newState;
+    }
+
+    public WindowManager.LayoutParams getLayoutParams() {
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+                PixelFormat.TRANSLUCENT);
+        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        lp.setTitle("BiometricDialogView");
+        lp.token = mWindowToken;
+        return lp;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
new file mode 100644
index 0000000..feef3a6d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.biometrics;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+
+/**
+ * This class loads the view for the system-provided dialog. The view consists of:
+ * Application Icon, Title, Subtitle, Description, Fingerprint Icon, Error/Help message area,
+ * and positive/negative buttons.
+ */
+public class FaceDialogView extends BiometricDialogView {
+    public FaceDialogView(Context context,
+            DialogViewCallback callback) {
+        super(context, callback);
+    }
+
+    @Override
+    protected int getHintStringResourceId() {
+        return R.string.face_dialog_looking_for_face;
+    }
+
+    @Override
+    protected int getAuthenticatedAccessibilityResourceId() {
+        if (mRequireConfirmation) {
+            return com.android.internal.R.string.face_authenticated_confirmation_required;
+        } else {
+            return com.android.internal.R.string.face_authenticated_no_confirmation_required;
+        }
+    }
+
+    @Override
+    protected int getIconDescriptionResourceId() {
+        return R.string.accessibility_face_dialog_face_icon;
+    }
+
+    @Override
+    protected void updateIcon(int lastState, int newState) {
+        Drawable icon = mContext.getDrawable(R.drawable.face_dialog_icon);
+
+        final ImageView faceIcon = getLayout().findViewById(R.id.biometric_icon);
+        faceIcon.setImageDrawable(icon);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
index 68c2c42..38a69a9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
@@ -17,32 +17,11 @@
 package com.android.systemui.biometrics;
 
 import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
-import android.hardware.biometrics.BiometricPrompt;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.animation.Interpolator;
-import android.widget.Button;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
 
-import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 
 /**
@@ -50,288 +29,27 @@
  * Application Icon, Title, Subtitle, Description, Fingerprint Icon, Error/Help message area,
  * and positive/negative buttons.
  */
-public class FingerprintDialogView extends LinearLayout {
-
+public class FingerprintDialogView extends BiometricDialogView {
     private static final String TAG = "FingerprintDialogView";
 
-    private static final int ANIMATION_DURATION_SHOW = 250; // ms
-    private static final int ANIMATION_DURATION_AWAY = 350; // ms
-
-    private static final int MSG_CLEAR_MESSAGE = 1;
-
-    private static final int STATE_NONE = 0;
-    private static final int STATE_FINGERPRINT = 1;
-    private static final int STATE_FINGERPRINT_ERROR = 2;
-    private static final int STATE_FINGERPRINT_AUTHENTICATED = 3;
-
-    private final IBinder mWindowToken = new Binder();
-    private final Interpolator mLinearOutSlowIn;
-    private final WindowManager mWindowManager;
-    private final float mAnimationTranslationOffset;
-    private final int mErrorColor;
-    private final int mTextColor;
-    private final int mFingerprintColor;
-    private final float mDisplayWidth;
-    private final DialogViewCallback mCallback;
-
-    private ViewGroup mLayout;
-    private final TextView mErrorText;
-    private Bundle mBundle;
-    private final LinearLayout mDialog;
-    private int mLastState;
-    private boolean mAnimatingAway;
-    private boolean mWasForceRemoved;
-
-    private final Runnable mShowAnimationRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mLayout.animate()
-                    .alpha(1f)
-                    .setDuration(ANIMATION_DURATION_SHOW)
-                    .setInterpolator(mLinearOutSlowIn)
-                    .withLayer()
-                    .start();
-            mDialog.animate()
-                    .translationY(0)
-                    .setDuration(ANIMATION_DURATION_SHOW)
-                    .setInterpolator(mLinearOutSlowIn)
-                    .withLayer()
-                    .start();
-        }
-    };
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch(msg.what) {
-                case MSG_CLEAR_MESSAGE:
-                    handleClearMessage();
-                    break;
-                default:
-                    Log.e(TAG, "Unhandled message: " + msg.what);
-                    break;
-            }
-        }
-    };
-
-    public FingerprintDialogView(Context context, DialogViewCallback callback) {
-        super(context);
-        mCallback = callback;
-        mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mAnimationTranslationOffset = getResources()
-                .getDimension(R.dimen.fingerprint_dialog_animation_translation_offset);
-        mErrorColor = Color.parseColor(
-                getResources().getString(R.color.fingerprint_dialog_error_color));
-        mTextColor = Color.parseColor(
-                getResources().getString(R.color.fingerprint_dialog_text_light_color));
-        mFingerprintColor = Color.parseColor(
-                getResources().getString(R.color.fingerprint_dialog_fingerprint_color));
-
-        DisplayMetrics metrics = new DisplayMetrics();
-        mWindowManager.getDefaultDisplay().getMetrics(metrics);
-        mDisplayWidth = metrics.widthPixels;
-
-        // Create the dialog
-        LayoutInflater factory = LayoutInflater.from(getContext());
-        mLayout = (ViewGroup) factory.inflate(R.layout.fingerprint_dialog, this, false);
-        addView(mLayout);
-
-        mDialog = mLayout.findViewById(R.id.dialog);
-
-        mErrorText = mLayout.findViewById(R.id.error);
-
-        mLayout.setOnKeyListener(new View.OnKeyListener() {
-            boolean downPressed = false;
-            @Override
-            public boolean onKey(View v, int keyCode, KeyEvent event) {
-                if (keyCode != KeyEvent.KEYCODE_BACK) {
-                    return false;
-                }
-                if (event.getAction() == KeyEvent.ACTION_DOWN && downPressed == false) {
-                    downPressed = true;
-                } else if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                    downPressed = false;
-                } else if (event.getAction() == KeyEvent.ACTION_UP && downPressed == true) {
-                    downPressed = false;
-                    mCallback.onUserCanceled();
-                }
-                return true;
-            }
-        });
-
-        final View space = mLayout.findViewById(R.id.space);
-        final View leftSpace = mLayout.findViewById(R.id.left_space);
-        final View rightSpace = mLayout.findViewById(R.id.right_space);
-        final Button negative = mLayout.findViewById(R.id.button2);
-        final Button positive = mLayout.findViewById(R.id.button1);
-
-        setDismissesDialog(space);
-        setDismissesDialog(leftSpace);
-        setDismissesDialog(rightSpace);
-
-        negative.setOnClickListener((View v) -> {
-            mCallback.onNegativePressed();
-        });
-
-        positive.setOnClickListener((View v) -> {
-            mCallback.onPositivePressed();
-        });
-
-        mLayout.setFocusableInTouchMode(true);
-        mLayout.requestFocus();
+    @Override
+    protected int getHintStringResourceId() {
+        return R.string.fingerprint_dialog_touch_sensor;
     }
 
     @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        final TextView title = mLayout.findViewById(R.id.title);
-        final TextView subtitle = mLayout.findViewById(R.id.subtitle);
-        final TextView description = mLayout.findViewById(R.id.description);
-        final Button negative = mLayout.findViewById(R.id.button2);
-        final Button positive = mLayout.findViewById(R.id.button1);
-
-        mDialog.getLayoutParams().width = (int) mDisplayWidth;
-
-        mLastState = STATE_NONE;
-        updateFingerprintIcon(STATE_FINGERPRINT);
-
-        title.setText(mBundle.getCharSequence(BiometricPrompt.KEY_TITLE));
-        title.setSelected(true);
-
-        final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
-        if (TextUtils.isEmpty(subtitleText)) {
-            subtitle.setVisibility(View.GONE);
-        } else {
-            subtitle.setVisibility(View.VISIBLE);
-            subtitle.setText(subtitleText);
-        }
-
-        final CharSequence descriptionText = mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
-        if (TextUtils.isEmpty(descriptionText)) {
-            description.setVisibility(View.GONE);
-        } else {
-            description.setVisibility(View.VISIBLE);
-            description.setText(descriptionText);
-        }
-
-        negative.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
-
-        final CharSequence positiveText =
-                mBundle.getCharSequence(BiometricPrompt.KEY_POSITIVE_TEXT);
-        positive.setText(positiveText); // needs to be set for marquee to work
-        if (positiveText != null) {
-            positive.setVisibility(View.VISIBLE);
-        } else {
-            positive.setVisibility(View.GONE);
-        }
-
-        if (!mWasForceRemoved) {
-            // Dim the background and slide the dialog up
-            mDialog.setTranslationY(mAnimationTranslationOffset);
-            mLayout.setAlpha(0f);
-            postOnAnimation(mShowAnimationRunnable);
-        } else {
-            // Show the dialog immediately
-            mLayout.animate().cancel();
-            mDialog.animate().cancel();
-            mDialog.setAlpha(1.0f);
-            mDialog.setTranslationY(0);
-            mLayout.setAlpha(1.0f);
-        }
-        mWasForceRemoved = false;
+    protected int getAuthenticatedAccessibilityResourceId() {
+        return com.android.internal.R.string.fingerprint_authenticated;
     }
 
-    private void setDismissesDialog(View v) {
-        v.setClickable(true);
-        v.setOnTouchListener((View view, MotionEvent event) -> {
-            mCallback.onUserCanceled();
-            return true;
-        });
+    @Override
+    protected int getIconDescriptionResourceId() {
+        return R.string.accessibility_fingerprint_dialog_fingerprint_icon;
     }
 
-    public void startDismiss() {
-        mAnimatingAway = true;
-
-        final Runnable endActionRunnable = new Runnable() {
-            @Override
-            public void run() {
-                mWindowManager.removeView(FingerprintDialogView.this);
-                mAnimatingAway = false;
-            }
-        };
-
-        postOnAnimation(new Runnable() {
-            @Override
-            public void run() {
-                mLayout.animate()
-                        .alpha(0f)
-                        .setDuration(ANIMATION_DURATION_AWAY)
-                        .setInterpolator(mLinearOutSlowIn)
-                        .withLayer()
-                        .start();
-                mDialog.animate()
-                        .translationY(mAnimationTranslationOffset)
-                        .setDuration(ANIMATION_DURATION_AWAY)
-                        .setInterpolator(mLinearOutSlowIn)
-                        .withLayer()
-                        .withEndAction(endActionRunnable)
-                        .start();
-            }
-        });
-    }
-
-    /**
-     * Force remove the window, cancelling any animation that's happening. This should only be
-     * called if we want to quickly show the dialog again (e.g. on rotation). Calling this method
-     * will cause the dialog to show without an animation the next time it's attached.
-     */
-    public void forceRemove() {
-        mLayout.animate().cancel();
-        mDialog.animate().cancel();
-        mWindowManager.removeView(FingerprintDialogView.this);
-        mAnimatingAway = false;
-        mWasForceRemoved = true;
-    }
-
-    public boolean isAnimatingAway() {
-        return mAnimatingAway;
-    }
-
-    public void setBundle(Bundle bundle) {
-        mBundle = bundle;
-    }
-
-    // Clears the temporary message and shows the help message.
-    private void handleClearMessage() {
-        updateFingerprintIcon(STATE_FINGERPRINT);
-        mErrorText.setText(R.string.fingerprint_dialog_touch_sensor);
-        mErrorText.setTextColor(mTextColor);
-    }
-
-    // Shows an error/help message
-    private void showTemporaryMessage(String message) {
-        mHandler.removeMessages(MSG_CLEAR_MESSAGE);
-        updateFingerprintIcon(STATE_FINGERPRINT_ERROR);
-        mErrorText.setText(message);
-        mErrorText.setTextColor(mErrorColor);
-        mErrorText.setContentDescription(message);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_MESSAGE),
-                BiometricPrompt.HIDE_DIALOG_DELAY);
-    }
-
-    public void showHelpMessage(String message) {
-        showTemporaryMessage(message);
-    }
-
-    public void showErrorMessage(String error) {
-        showTemporaryMessage(error);
-        mCallback.onErrorShown();
-    }
-
-    private void updateFingerprintIcon(int newState) {
-        Drawable icon  = getAnimationForTransition(mLastState, newState);
+    @Override
+    protected void updateIcon(int lastState, int newState) {
+        Drawable icon = getAnimationForTransition(lastState, newState);
 
         if (icon == null) {
             Log.e(TAG, "Animation not found");
@@ -342,25 +60,28 @@
                 ? (AnimatedVectorDrawable) icon
                 : null;
 
-        final ImageView fingerprint_icon = mLayout.findViewById(R.id.fingerprint_icon);
-        fingerprint_icon.setImageDrawable(icon);
+        final ImageView fingerprintIcon = getLayout().findViewById(R.id.biometric_icon);
+        fingerprintIcon.setImageDrawable(icon);
 
-        if (animation != null && shouldAnimateForTransition(mLastState, newState)) {
+        if (animation != null && shouldAnimateForTransition(lastState, newState)) {
             animation.forceAnimationOnUI();
             animation.start();
         }
+    }
 
-        mLastState = newState;
+    public FingerprintDialogView(Context context,
+            DialogViewCallback callback) {
+        super(context, callback);
     }
 
     private boolean shouldAnimateForTransition(int oldState, int newState) {
-        if (oldState == STATE_NONE && newState == STATE_FINGERPRINT) {
+        if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
             return false;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
             return true;
-        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
+        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
             return true;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_AUTHENTICATED) {
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
             // TODO(b/77328470): add animation when fingerprint is authenticated
             return false;
         }
@@ -369,32 +90,18 @@
 
     private Drawable getAnimationForTransition(int oldState, int newState) {
         int iconRes;
-        if (oldState == STATE_NONE && newState == STATE_FINGERPRINT) {
+        if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
             iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
             iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
+        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
             iconRes = R.drawable.fingerprint_dialog_error_to_fp;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_AUTHENTICATED) {
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
             // TODO(b/77328470): add animation when fingerprint is authenticated
             iconRes = R.drawable.fingerprint_dialog_error_to_fp;
-        }
-        else {
+        } else {
             return null;
         }
         return mContext.getDrawable(iconRes);
     }
-
-    public WindowManager.LayoutParams getLayoutParams() {
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                PixelFormat.TRANSLUCENT);
-        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        lp.setTitle("FingerprintDialogView");
-        lp.token = mWindowToken;
-        return lp;
-    }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index d6a1cf0..5739c99 100644
--- a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -16,7 +16,6 @@
 package com.android.systemui.car;
 
 import android.content.Context;
-import android.service.notification.StatusBarNotification;
 
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.NotificationData;
@@ -41,7 +40,7 @@
     }
 
     @Override
-    public boolean shouldPeek(NotificationData.Entry entry, StatusBarNotification sbn) {
+    public boolean shouldHeadsUp(NotificationData.Entry entry) {
         // 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.
@@ -49,6 +48,6 @@
             return false;
         }
 
-        return super.shouldPeek(entry, sbn);
+        return super.shouldHeadsUp(entry);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 6a29299..bb05980 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -48,7 +48,15 @@
     void onIgnoreTouchWhilePulsing(boolean ignore);
 
     interface Callback {
-        default void onNotificationHeadsUp() {}
+        /**
+         * Called when a high priority notification is added.
+         */
+        default void onNotificationAlerted() {}
+
+        /**
+         * Called when battery state or power save mode changes.
+         * @param active whether power save is active or not
+         */
         default void onPowerSaveChanged(boolean active) {}
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index e6026c1..21b21d9 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -44,7 +44,7 @@
     public static final int PULSE_REASON_SENSOR_PICKUP = 3;
     public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
     public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
-    public static final int PULSE_REASON_SENSOR_REACH = 6;
+    public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 6;
     public static final int REASON_SENSOR_WAKE_UP = 7;
 
     private static boolean sRegisterKeyguardCallback = true;
@@ -177,9 +177,9 @@
         log("state " + state);
     }
 
-    public static void traceReachWakeUp() {
+    public static void traceWakeLockScreenWakeUp() {
         if (!ENABLED) return;
-        log("reachWakeUp");
+        log("wakeLockScreenWakeUp");
     }
 
     public static void traceProximityResult(Context context, boolean near, long millis,
@@ -199,7 +199,7 @@
             case PULSE_REASON_SENSOR_PICKUP: return "pickup";
             case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
             case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
-            case PULSE_REASON_SENSOR_REACH: return "reach";
+            case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakeLockScreen";
             case REASON_SENSOR_WAKE_UP: return "wakeup";
             default: throw new IllegalArgumentException("bad reason: " + pulseReason);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 36b2347..c566460 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -16,11 +16,15 @@
 
 package com.android.systemui.doze;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -31,7 +35,12 @@
 /**
  * Controls the screen brightness when dozing.
  */
-public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListener {
+public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachine.Part,
+        SensorEventListener {
+    protected static final String ACTION_AOD_BRIGHTNESS =
+            "com.android.systemui.doze.AOD_BRIGHTNESS";
+    protected static final String BRIGHTNESS_BUCKET = "brightness_bucket";
+
     private final Context mContext;
     private final DozeMachine.Service mDozeService;
     private final DozeHost mDozeHost;
@@ -40,36 +49,52 @@
     private final Sensor mLightSensor;
     private final int[] mSensorToBrightness;
     private final int[] mSensorToScrimOpacity;
+    private final boolean mDebuggable;
 
     private boolean mRegistered;
     private int mDefaultDozeBrightness;
     private boolean mPaused = false;
     private int mLastSensorValue = -1;
 
+    /**
+     * Debug value used for emulating various display brightness buckets:
+     *
+     * {@code am broadcast -p com.android.systemui -a com.android.systemui.doze.AOD_BRIGHTNESS
+     * --ei brightness_bucket 1}
+     */
+    private int mDebugBrightnessBucket = -1;
+
+    @VisibleForTesting
     public DozeScreenBrightness(Context context, DozeMachine.Service service,
             SensorManager sensorManager, Sensor lightSensor, DozeHost host,
             Handler handler, int defaultDozeBrightness, int[] sensorToBrightness,
-            int[] sensorToScrimOpacity) {
+            int[] sensorToScrimOpacity, boolean debuggable) {
         mContext = context;
         mDozeService = service;
         mSensorManager = sensorManager;
         mLightSensor = lightSensor;
         mDozeHost = host;
         mHandler = handler;
+        mDebuggable = debuggable;
 
         mDefaultDozeBrightness = defaultDozeBrightness;
         mSensorToBrightness = sensorToBrightness;
         mSensorToScrimOpacity = sensorToScrimOpacity;
+
+        if (mDebuggable) {
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(ACTION_AOD_BRIGHTNESS);
+            mContext.registerReceiverAsUser(this, UserHandle.ALL, filter, null, null);
+        }
     }
 
-    @VisibleForTesting
     public DozeScreenBrightness(Context context, DozeMachine.Service service,
             SensorManager sensorManager, Sensor lightSensor, DozeHost host,
             Handler handler, AlwaysOnDisplayPolicy policy) {
         this(context, service, sensorManager, lightSensor, host, handler,
                 context.getResources().getInteger(
                         com.android.internal.R.integer.config_screenBrightnessDoze),
-                policy.screenBrightnessArray, policy.dimmingScrimArray);
+                policy.screenBrightnessArray, policy.dimmingScrimArray, Build.IS_DEBUGGABLE);
     }
 
     @Override
@@ -87,7 +112,7 @@
                 resetBrightnessToDefault();
                 break;
             case FINISH:
-                setLightSensorEnabled(false);
+                onDestroy();
                 break;
         }
         if (newState != DozeMachine.State.FINISH) {
@@ -95,6 +120,13 @@
         }
     }
 
+    private void onDestroy() {
+        setLightSensorEnabled(false);
+        if (mDebuggable) {
+            mContext.unregisterReceiver(this);
+        }
+    }
+
     @Override
     public void onSensorChanged(SensorEvent event) {
         Trace.beginSection("DozeScreenBrightness.onSensorChanged" + event.values[0]);
@@ -110,7 +142,9 @@
 
     private void updateBrightnessAndReady() {
         if (mRegistered) {
-            int brightness = computeBrightness(mLastSensorValue);
+            int sensorValue = mDebugBrightnessBucket == -1
+                    ? mLastSensorValue : mDebugBrightnessBucket;
+            int brightness = computeBrightness(sensorValue);
             boolean brightnessReady = brightness > 0;
             if (brightnessReady) {
                 mDozeService.setDozeScreenBrightness(clampToUserSetting(brightness));
@@ -125,7 +159,7 @@
                 scrimOpacity = 255;
             } else if (brightnessReady) {
                 // Only unblank scrim once brightness is ready.
-                scrimOpacity = computeScrimOpacity(mLastSensorValue);
+                scrimOpacity = computeScrimOpacity(sensorValue);
             }
             if (scrimOpacity >= 0) {
                 mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
@@ -184,4 +218,9 @@
         }
     }
 
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        mDebugBrightnessBucket = intent.getIntExtra(BRIGHTNESS_BUCKET, -1);
+        updateBrightnessAndReady();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index f9dfb5d..7013947 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -113,10 +113,10 @@
                         true /* reports touch coordinates */,
                         true /* touchscreen */),
                 new TriggerSensor(
-                        findSensorWithType(config.reachSensorType()),
-                        Settings.Secure.DOZE_REACH_GESTURE,
+                        findSensorWithType(config.wakeLockScreenSensorType()),
+                        Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
                         true /* configured */,
-                        DozeLog.PULSE_REASON_SENSOR_REACH,
+                        DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
                         false /* reports touch coordinates */,
                         false /* touchscreen */),
                 new WakeScreenSensor(),
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 7339304..c61e10a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -26,7 +26,7 @@
 import com.android.systemui.plugins.DozeServicePlugin;
 import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 1589969..cb91d78 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -128,7 +128,7 @@
         boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
         boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
         boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
-        boolean isReach = pulseReason == DozeLog.PULSE_REASON_SENSOR_REACH;
+        boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
 
         if (isLongPress) {
             requestPulse(pulseReason, sensorPerformedProxCheck);
@@ -141,7 +141,7 @@
                 if (isDoubleTap) {
                     mDozeHost.onDoubleTap(screenX, screenY);
                     mMachine.wakeUp();
-                } else if (isPickup || isReach) {
+                } else if (isPickup || isWakeLockScreen) {
                     mMachine.wakeUp();
                 } else {
                     mDozeHost.extendPulse();
@@ -156,8 +156,8 @@
             final boolean withinVibrationThreshold =
                     timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
             DozeLog.tracePickupWakeUp(mContext, withinVibrationThreshold);
-        } else if (isReach) {
-            DozeLog.traceReachWakeUp();
+        } else if (isWakeLockScreen) {
+            DozeLog.traceWakeLockScreenWakeUp();
         }
     }
 
@@ -409,7 +409,7 @@
 
     private DozeHost.Callback mHostCallback = new DozeHost.Callback() {
         @Override
-        public void onNotificationHeadsUp() {
+        public void onNotificationAlerted() {
             onNotification();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt b/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
new file mode 100644
index 0000000..d1e5059
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
@@ -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.systemui.doze.util
+
+import android.util.MathUtils
+
+private const val MILLIS_PER_MINUTES = 1000 * 60f
+private const val BURN_IN_PREVENTION_PERIOD_Y = 521f
+private const val BURN_IN_PREVENTION_PERIOD_X = 83f
+
+/**
+ * Returns the translation offset that should be used to avoid burn in at
+ * the current time (in pixels.)
+ *
+ * @param amplitude Maximum translation that will be interpolated.
+ * @param xAxis If we're moving on X or Y.
+ */
+fun getBurnInOffset(amplitude: Int, xAxis: Boolean): Int {
+    return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
+            amplitude.toFloat(),
+            if (xAxis) BURN_IN_PREVENTION_PERIOD_X else BURN_IN_PREVENTION_PERIOD_Y).toInt()
+}
+
+/**
+ * Implements a continuous, piecewise linear, periodic zig-zag function
+ *
+ * Can be thought of as a linear approximation of abs(sin(x)))
+ *
+ * @param period period of the function, ie. zigzag(x + period) == zigzag(x)
+ * @param amplitude maximum value of the function
+ * @return a value between 0 and amplitude
+ */
+private fun zigzag(x: Float, amplitude: Float, period: Float): Float {
+    val xprime = x % period / (period / 2)
+    val interpolationAmount = if (xprime <= 1) xprime else 2 - xprime
+    return MathUtils.lerp(0f, amplitude, interpolationAmount)
+}
\ No newline at end of file
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/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
index 745f312..d833c16 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
@@ -19,9 +19,6 @@
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.systemui.Dependency;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-
 import java.util.ArrayList;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1655c01..4988f07 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -20,6 +20,9 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.internal.telephony.IccCardConstants.State.ABSENT;
+import static com.android.internal.telephony.IccCardConstants.State.PIN_REQUIRED;
+import static com.android.internal.telephony.IccCardConstants.State.PUK_REQUIRED;
+import static com.android.internal.telephony.IccCardConstants.State.READY;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
@@ -30,7 +33,6 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
-import android.hardware.biometrics.BiometricSourceType;
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -38,6 +40,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.UserInfo;
+import android.hardware.biometrics.BiometricSourceType;
 import android.media.AudioManager;
 import android.media.SoundPool;
 import android.os.Bundle;
@@ -58,6 +61,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.view.ViewGroup;
 import android.view.WindowManagerPolicyConstants;
 import android.view.animation.Animation;
@@ -70,21 +74,21 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardStateCallback;
 import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardConstants;
 import com.android.keyguard.KeyguardDisplayManager;
 import com.android.keyguard.KeyguardSecurityView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.classifier.FalsingManager;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 
@@ -274,6 +278,12 @@
 
     private KeyguardUpdateMonitor mUpdateMonitor;
 
+    /**
+     * Last SIM state reported by the telephony system.
+     * Index is the slotId - in case of multiple SIM cards.
+     */
+    private final SparseArray<IccCardConstants.State> mLastSimStates = new SparseArray<>();
+
     private boolean mDeviceInteractive;
     private boolean mGoingToSleep;
 
@@ -450,6 +460,14 @@
                 }
             }
 
+            boolean simWasLocked;
+            synchronized (KeyguardViewMediator.this) {
+                IccCardConstants.State lastState = mLastSimStates.get(slotId);
+                simWasLocked = (lastState == PIN_REQUIRED || lastState == PUK_REQUIRED)
+                    && simState == READY;
+                mLastSimStates.append(slotId, simState);
+            }
+
             switch (simState) {
                 case NOT_READY:
                 case ABSENT:
@@ -503,6 +521,9 @@
                 case READY:
                     synchronized (KeyguardViewMediator.this) {
                         if (DEBUG_SIM_STATES) Log.d(TAG, "READY, reset state? " + mShowing);
+                        if (mShowing && simWasLocked) {
+                            resetStateLocked();
+                        }
                         mLockWhenSimRemoved = true;
                     }
                     break;
@@ -1917,6 +1938,12 @@
             mStatusBarManager = (StatusBarManager)
                     mContext.getSystemService(Context.STATUS_BAR_SERVICE);
         }
+
+        // TODO(b/113914868): investigation log for disappearing home button
+        Log.d(TAG, "adjustStatusBarLocked (b/113914868): mShowing=" + mShowing
+                + " mStatusBarManager=" + mStatusBarManager + " mOccluded="
+                + mOccluded + " isSecure=" + isSecure() + " force=" + forceHideHomeRecentsButtons);
+
         if (mStatusBarManager == null) {
             Log.w(TAG, "Could not get status bar manager");
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
index 0cedf98..74f7706 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
@@ -19,7 +19,6 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
-import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
 import android.app.KeyguardManager;
 import android.content.ComponentName;
@@ -29,11 +28,9 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
-
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
 
 public class WorkLockActivityController {
     private static final String TAG = WorkLockActivityController.class.getSimpleName();
@@ -111,7 +108,7 @@
         }
     }
 
-    private final SysUiTaskStackChangeListener mLockListener = new SysUiTaskStackChangeListener() {
+    private final TaskStackChangeListener mLockListener = new TaskStackChangeListener() {
         @Override
         public void onTaskProfileLocked(int taskId, int userId) {
             startWorkChallengeInTask(taskId, userId);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
index b7164cb..864a6f9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -21,11 +21,12 @@
 
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
-
+import android.os.UserHandle;
+import android.os.UserManager;
 import com.android.systemui.SystemUI;
-import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.component.ExpandPipEvent;
 import com.android.systemui.statusbar.CommandQueue;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
@@ -47,8 +48,8 @@
         }
 
         // Ensure that we are the primary user's SystemUI.
-        final int processUser = SystemServicesProxy.getInstance(mContext).getProcessUser();
-        if (!SystemServicesProxy.getInstance(mContext).isSystemUser(processUser)) {
+        final int processUser = UserManager.get(mContext).getUserHandle();
+        if (processUser != UserHandle.USER_SYSTEM) {
             throw new IllegalStateException("Non-primary Pip component not currently supported.");
         }
 
@@ -58,6 +59,7 @@
         mPipManager.initialize(mContext);
 
         getComponent(CommandQueue.class).addCallbacks(this);
+        putComponent(PipUI.class, this);
     }
 
     @Override
@@ -65,6 +67,10 @@
         mPipManager.showPictureInPictureMenu();
     }
 
+    public void expandPip() {
+        EventBus.getDefault().send(new ExpandPipEvent());
+    }
+
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/ForegroundThread.java b/packages/SystemUI/src/com/android/systemui/pip/phone/ForegroundThread.java
new file mode 100644
index 0000000..9bf46bb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/ForegroundThread.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.pip.phone;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Similar to {@link com.android.internal.os.BackgroundThread}, this is a shared singleton
+ * foreground thread for each process.
+ */
+public final class ForegroundThread extends HandlerThread {
+    private static ForegroundThread sInstance;
+    private static Handler sHandler;
+
+    private ForegroundThread() {
+        super("recents.fg");
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new ForegroundThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+        }
+    }
+
+    public static ForegroundThread get() {
+        synchronized (ForegroundThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (ForegroundThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
index 5547e2d..9ce2606 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -19,21 +19,17 @@
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
-import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnLayoutChangeListener;
-import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 import android.widget.FrameLayout;
-
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 
 public class PipDismissViewController {
 
@@ -59,7 +55,7 @@
         if (mDismissView == null) {
             // Determine sizes for the view
             final Rect stableInsets = new Rect();
-            SystemServicesProxy.getInstance(mContext).getStableInsets(stableInsets);
+            WindowManagerWrapper.getInstance().getStableInsets(stableInsets);
             final Point windowSize = new Point();
             mWindowManager.getDefaultDisplay().getRealSize(windowSize);
             final int gradientHeight = mContext.getResources().getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index ee15655..04746c1 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -17,7 +17,6 @@
 package com.android.systemui.pip.phone;
 
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
@@ -36,15 +35,15 @@
 import android.view.IPinnedStackListener;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
-
+import com.android.systemui.Dependency;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.pip.BasePipManager;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.component.ExpandPipEvent;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.InputConsumerController;
-
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import java.io.PrintWriter;
 
 /**
@@ -72,7 +71,7 @@
     /**
      * Handler for system task stack changes.
      */
-    SysUiTaskStackChangeListener mTaskStackListener = new SysUiTaskStackChangeListener() {
+    TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
             mTouchHandler.onActivityPinned();
@@ -80,7 +79,9 @@
             mMenuController.onActivityPinned();
             mAppOpsListener.onActivityPinned(packageName);
 
-            SystemServicesProxy.getInstance(mContext).setPipVisibility(true);
+            Dependency.get(UiOffloadThread.class).submit(() -> {
+                WindowManagerWrapper.getInstance().setPipVisibility(true);
+            });
         }
 
         @Override
@@ -93,7 +94,9 @@
             mTouchHandler.onActivityUnpinned(topActivity);
             mAppOpsListener.onActivityUnpinned();
 
-            SystemServicesProxy.getInstance(mContext).setPipVisibility(topActivity != null);
+            Dependency.get(UiOffloadThread.class).submit(() -> {
+                WindowManagerWrapper.getInstance().setPipVisibility(topActivity != null);
+            });
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index f0ab046..ce7da79 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -30,7 +30,6 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.ActivityManager.StackInfo;
-import android.app.ActivityTaskManager;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
 import android.content.Context;
@@ -43,14 +42,11 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.animation.Interpolator;
-
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.policy.PipSnapAlgorithm;
-import com.android.systemui.recents.misc.ForegroundThread;
-import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.statusbar.FlingAnimationUtils;
-
 import java.io.PrintWriter;
 
 /**
@@ -116,7 +112,7 @@
      */
     void onConfigurationChanged() {
         mSnapAlgorithm.onConfigurationChanged();
-        SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+        WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 020c550..43e9db7 100755
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -16,6 +16,11 @@
 
 package com.android.systemui.pip.tv;
 
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
@@ -44,22 +49,17 @@
 import android.view.IPinnedStackListener;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
-
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.pip.BasePipManager;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.Display.DEFAULT_DISPLAY;
-
 /**
  * Manages the picture-in-picture (PIP) UI and states.
  */
@@ -630,7 +630,7 @@
         return false;
     }
 
-    private SysUiTaskStackChangeListener mTaskStackListener = new SysUiTaskStackChangeListener() {
+    private TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onTaskStackChanged() {
             if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
@@ -754,7 +754,9 @@
     }
 
     private void updatePipVisibility(final boolean visible) {
-        SystemServicesProxy.getInstance(mContext).setPipVisibility(visible);
+        Dependency.get(UiOffloadThread.class).submit(() -> {
+            WindowManagerWrapper.getInstance().setPipVisibility(visible);
+        });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
index c58d889..03daa95 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
@@ -18,6 +18,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.PluginDependency.DependencyProvider;
+import com.android.systemui.shared.plugins.PluginManager;
 
 public class PluginDependencyProvider extends DependencyProvider {
 
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
new file mode 100644
index 0000000..ac0a226
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginInitializerImpl.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 com.android.systemui.plugins;
+
+import android.content.Context;
+import android.os.Looper;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.shared.plugins.PluginEnabler;
+import com.android.systemui.shared.plugins.PluginInitializer;
+import com.android.systemui.R;
+
+public class PluginInitializerImpl implements PluginInitializer {
+    @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);
+            }
+        };
+    }
+
+    @Override
+    public String[] getWhitelistedPlugins(Context context) {
+        return context.getResources().getStringArray(R.array.config_pluginWhitelist);
+    }
+
+    public PluginEnabler getPluginEnabler(Context context) {
+        return new PluginEnablerImpl(context);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
deleted file mode 100644
index d5541e9..0000000
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.app.Notification;
-import android.app.Notification.Action;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.UserHandle;
-import android.util.Log;
-import android.view.LayoutInflater;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.systemui.plugins.VersionInfo.InvalidVersionException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PluginInstanceManager<T extends Plugin> {
-
-    private static final boolean DEBUG = false;
-
-    private static final String TAG = "PluginInstanceManager";
-    public static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
-
-    private final Context mContext;
-    private final PluginListener<T> mListener;
-    private final String mAction;
-    private final boolean mAllowMultiple;
-    private final VersionInfo mVersion;
-
-    @VisibleForTesting
-    final MainHandler mMainHandler;
-    @VisibleForTesting
-    final PluginHandler mPluginHandler;
-    private final boolean isDebuggable;
-    private final PackageManager mPm;
-    private final PluginManagerImpl mManager;
-
-    PluginInstanceManager(Context context, String action, PluginListener<T> listener,
-            boolean allowMultiple, Looper looper, VersionInfo version, PluginManagerImpl manager) {
-        this(context, context.getPackageManager(), action, listener, allowMultiple, looper, version,
-                manager, Build.IS_DEBUGGABLE);
-    }
-
-    @VisibleForTesting
-    PluginInstanceManager(Context context, PackageManager pm, String action,
-            PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version,
-            PluginManagerImpl manager, boolean debuggable) {
-        mMainHandler = new MainHandler(Looper.getMainLooper());
-        mPluginHandler = new PluginHandler(looper);
-        mManager = manager;
-        mContext = context;
-        mPm = pm;
-        mAction = action;
-        mListener = listener;
-        mAllowMultiple = allowMultiple;
-        mVersion = version;
-        isDebuggable = debuggable;
-    }
-
-    public PluginInfo<T> getPlugin() {
-        if (Looper.myLooper() != Looper.getMainLooper()) {
-            throw new RuntimeException("Must be called from UI thread");
-        }
-        mPluginHandler.handleQueryPlugins(null /* All packages */);
-        if (mPluginHandler.mPlugins.size() > 0) {
-            mMainHandler.removeMessages(MainHandler.PLUGIN_CONNECTED);
-            PluginInfo<T> info = mPluginHandler.mPlugins.get(0);
-            PluginPrefs.setHasPlugins(mContext);
-            info.mPlugin.onCreate(mContext, info.mPluginContext);
-            return info;
-        }
-        return null;
-    }
-
-    public void loadAll() {
-        if (DEBUG) Log.d(TAG, "startListening");
-        mPluginHandler.sendEmptyMessage(PluginHandler.QUERY_ALL);
-    }
-
-    public void destroy() {
-        if (DEBUG) Log.d(TAG, "stopListening");
-        ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins);
-        for (PluginInfo plugin : plugins) {
-            mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED,
-                    plugin.mPlugin).sendToTarget();
-        }
-    }
-
-    public void onPackageRemoved(String pkg) {
-        mPluginHandler.obtainMessage(PluginHandler.REMOVE_PKG, pkg).sendToTarget();
-    }
-
-    public void onPackageChange(String pkg) {
-        mPluginHandler.obtainMessage(PluginHandler.REMOVE_PKG, pkg).sendToTarget();
-        mPluginHandler.obtainMessage(PluginHandler.QUERY_PKG, pkg).sendToTarget();
-    }
-
-    public boolean checkAndDisable(String className) {
-        boolean disableAny = false;
-        ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins);
-        for (PluginInfo info : plugins) {
-            if (className.startsWith(info.mPackage)) {
-                disable(info);
-                disableAny = true;
-            }
-        }
-        return disableAny;
-    }
-
-    public boolean disableAll() {
-        ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins);
-        for (int i = 0; i < plugins.size(); i++) {
-            disable(plugins.get(i));
-        }
-        return plugins.size() != 0;
-    }
-
-    private void disable(PluginInfo info) {
-        // Live by the sword, die by the sword.
-        // Misbehaving plugins get disabled and won't come back until uninstall/reinstall.
-
-        // If a plugin is detected in the stack of a crash then this will be called for that
-        // 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);
-    }
-
-    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
-        ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins);
-        for (PluginInfo info : plugins) {
-            if (info.mPlugin.getClass().getName().equals(p.getClass().getName())) {
-                return info.mVersion != null && info.mVersion.hasClass(cls);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s@%s (action=%s)",
-                getClass().getSimpleName(), hashCode(), mAction);
-    }
-
-    private class MainHandler extends Handler {
-        private static final int PLUGIN_CONNECTED = 1;
-        private static final int PLUGIN_DISCONNECTED = 2;
-
-        public MainHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case PLUGIN_CONNECTED:
-                    if (DEBUG) Log.d(TAG, "onPluginConnected");
-                    PluginPrefs.setHasPlugins(mContext);
-                    PluginInfo<T> info = (PluginInfo<T>) msg.obj;
-                    mManager.handleWtfs();
-                    if (!(msg.obj instanceof PluginFragment)) {
-                        // Only call onDestroy for plugins that aren't fragments, as fragments
-                        // will get the onCreate as part of the fragment lifecycle.
-                        info.mPlugin.onCreate(mContext, info.mPluginContext);
-                    }
-                    mListener.onPluginConnected(info.mPlugin, info.mPluginContext);
-                    break;
-                case PLUGIN_DISCONNECTED:
-                    if (DEBUG) Log.d(TAG, "onPluginDisconnected");
-                    mListener.onPluginDisconnected((T) msg.obj);
-                    if (!(msg.obj instanceof PluginFragment)) {
-                        // Only call onDestroy for plugins that aren't fragments, as fragments
-                        // will get the onDestroy as part of the fragment lifecycle.
-                        ((T) msg.obj).onDestroy();
-                    }
-                    break;
-                default:
-                    super.handleMessage(msg);
-                    break;
-            }
-        }
-    }
-
-    private class PluginHandler extends Handler {
-        private static final int QUERY_ALL = 1;
-        private static final int QUERY_PKG = 2;
-        private static final int REMOVE_PKG = 3;
-
-        private final ArrayList<PluginInfo<T>> mPlugins = new ArrayList<>();
-
-        public PluginHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case QUERY_ALL:
-                    if (DEBUG) Log.d(TAG, "queryAll " + mAction);
-                    for (int i = mPlugins.size() - 1; i >= 0; i--) {
-                        PluginInfo<T> plugin = mPlugins.get(i);
-                        mListener.onPluginDisconnected(plugin.mPlugin);
-                        if (!(plugin.mPlugin instanceof PluginFragment)) {
-                            // Only call onDestroy for plugins that aren't fragments, as fragments
-                            // will get the onDestroy as part of the fragment lifecycle.
-                            plugin.mPlugin.onDestroy();
-                        }
-                    }
-                    mPlugins.clear();
-                    handleQueryPlugins(null);
-                    break;
-                case REMOVE_PKG:
-                    String pkg = (String) msg.obj;
-                    for (int i = mPlugins.size() - 1; i >= 0; i--) {
-                        final PluginInfo<T> plugin = mPlugins.get(i);
-                        if (plugin.mPackage.equals(pkg)) {
-                            mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED,
-                                    plugin.mPlugin).sendToTarget();
-                            mPlugins.remove(i);
-                        }
-                    }
-                    break;
-                case QUERY_PKG:
-                    String p = (String) msg.obj;
-                    if (DEBUG) Log.d(TAG, "queryPkg " + p + " " + mAction);
-                    if (mAllowMultiple || (mPlugins.size() == 0)) {
-                        handleQueryPlugins(p);
-                    } else {
-                        if (DEBUG) Log.d(TAG, "Too many of " + mAction);
-                    }
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-
-        private void handleQueryPlugins(String pkgName) {
-            // This isn't actually a service and shouldn't ever be started, but is
-            // a convenient PM based way to manage our plugins.
-            Intent intent = new Intent(mAction);
-            if (pkgName != null) {
-                intent.setPackage(pkgName);
-            }
-            List<ResolveInfo> result =
-                    mPm.queryIntentServices(intent, 0);
-            if (DEBUG) Log.d(TAG, "Found " + result.size() + " plugins");
-            if (result.size() > 1 && !mAllowMultiple) {
-                // TODO: Show warning.
-                Log.w(TAG, "Multiple plugins found for " + mAction);
-                return;
-            }
-            for (ResolveInfo info : result) {
-                ComponentName name = new ComponentName(info.serviceInfo.packageName,
-                        info.serviceInfo.name);
-                PluginInfo<T> t = handleLoadPlugin(name);
-                if (t == null) continue;
-                mMainHandler.obtainMessage(mMainHandler.PLUGIN_CONNECTED, t).sendToTarget();
-                mPlugins.add(t);
-            }
-        }
-
-        protected PluginInfo<T> handleLoadPlugin(ComponentName component) {
-            // This was already checked, but do it again here to make extra extra sure, we don't
-            // use these on production builds.
-            if (!isDebuggable) {
-                // Never ever ever allow these on production builds, they are only for prototyping.
-                Log.d(TAG, "Somehow hit second debuggable check");
-                return null;
-            }
-            String pkg = component.getPackageName();
-            String cls = component.getClassName();
-            try {
-                ApplicationInfo info = mPm.getApplicationInfo(pkg, 0);
-                // TODO: This probably isn't needed given that we don't have IGNORE_SECURITY on
-                if (mPm.checkPermission(PLUGIN_PERMISSION, pkg)
-                        != PackageManager.PERMISSION_GRANTED) {
-                    Log.d(TAG, "Plugin doesn't have permission: " + pkg);
-                    return null;
-                }
-                // Create our own ClassLoader so we can use our own code as the parent.
-                ClassLoader classLoader = mManager.getClassLoader(info.sourceDir, info.packageName);
-                Context pluginContext = new PluginContextWrapper(
-                        mContext.createApplicationContext(info, 0), classLoader);
-                Class<?> pluginClass = Class.forName(cls, true, classLoader);
-                // TODO: Only create the plugin before version check if we need it for
-                // legacy version check.
-                T plugin = (T) pluginClass.newInstance();
-                try {
-                    VersionInfo version = checkVersion(pluginClass, plugin, mVersion);
-                    if (DEBUG) Log.d(TAG, "createPlugin");
-                    return new PluginInfo(pkg, cls, plugin, pluginContext, version);
-                } catch (InvalidVersionException e) {
-                    final int icon = mContext.getResources().getIdentifier("tuner", "drawable",
-                            mContext.getPackageName());
-                    final int color = Resources.getSystem().getIdentifier(
-                            "system_notification_accent_color", "color", "android");
-                    final Notification.Builder nb = new Notification.Builder(mContext,
-                            PluginManager.NOTIFICATION_CHANNEL_ID)
-                                    .setStyle(new Notification.BigTextStyle())
-                                    .setSmallIcon(icon)
-                                    .setWhen(0)
-                                    .setShowWhen(false)
-                                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                                    .setColor(mContext.getColor(color));
-                    String label = cls;
-                    try {
-                        label = mPm.getServiceInfo(component, 0).loadLabel(mPm).toString();
-                    } catch (NameNotFoundException e2) {
-                    }
-                    if (!e.isTooNew()) {
-                        // Localization not required as this will never ever appear in a user build.
-                        nb.setContentTitle("Plugin \"" + label + "\" is too old")
-                                .setContentText("Contact plugin developer to get an updated"
-                                        + " version.\n" + e.getMessage());
-                    } else {
-                        // Localization not required as this will never ever appear in a user build.
-                        nb.setContentTitle("Plugin \"" + label + "\" is too new")
-                                .setContentText("Check to see if an OTA is available.\n"
-                                        + e.getMessage());
-                    }
-                    Intent i = new Intent(PluginManagerImpl.DISABLE_PLUGIN).setData(
-                            Uri.parse("package://" + component.flattenToString()));
-                    PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
-                    nb.addAction(new Action.Builder(null, "Disable plugin", pi).build());
-                    mContext.getSystemService(NotificationManager.class)
-                            .notifyAsUser(cls, SystemMessage.NOTE_PLUGIN, nb.build(),
-                                    UserHandle.ALL);
-                    // TODO: Warn user.
-                    Log.w(TAG, "Plugin has invalid interface version " + plugin.getVersion()
-                            + ", expected " + mVersion);
-                    return null;
-                }
-            } catch (Throwable e) {
-                Log.w(TAG, "Couldn't load plugin: " + pkg, e);
-                return null;
-            }
-        }
-
-        private VersionInfo checkVersion(Class<?> pluginClass, T plugin, VersionInfo version)
-                throws InvalidVersionException {
-            VersionInfo pv = new VersionInfo().addClass(pluginClass);
-            if (pv.hasVersionInfo()) {
-                version.checkVersion(pv);
-            } else {
-                int fallbackVersion = plugin.getVersion();
-                if (fallbackVersion != version.getDefaultVersion()) {
-                    throw new InvalidVersionException("Invalid legacy version", false);
-                }
-                return null;
-            }
-            return pv;
-        }
-    }
-
-    public static class PluginContextWrapper extends ContextWrapper {
-        private final ClassLoader mClassLoader;
-        private LayoutInflater mInflater;
-
-        public PluginContextWrapper(Context base, ClassLoader classLoader) {
-            super(base);
-            mClassLoader = classLoader;
-        }
-
-        @Override
-        public ClassLoader getClassLoader() {
-            return mClassLoader;
-        }
-
-        @Override
-        public Object getSystemService(String name) {
-            if (LAYOUT_INFLATER_SERVICE.equals(name)) {
-                if (mInflater == null) {
-                    mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
-                }
-                return mInflater;
-            }
-            return getBaseContext().getSystemService(name);
-        }
-    }
-
-    static class PluginInfo<T> {
-        private final Context mPluginContext;
-        private final VersionInfo mVersion;
-        private String mClass;
-        T mPlugin;
-        String mPackage;
-
-        public PluginInfo(String pkg, String cls, T plugin, Context pluginContext,
-                VersionInfo info) {
-            mPlugin = plugin;
-            mClass = cls;
-            mPackage = pkg;
-            mPluginContext = pluginContext;
-            mVersion = info;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java
deleted file mode 100644
index 298eaf1..0000000
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.text.TextUtils;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-public interface PluginManager {
-
-    String PLUGIN_CHANGED = "com.android.systemui.action.PLUGIN_CHANGED";
-
-    // must be one of the channels created in NotificationChannels.java
-    String NOTIFICATION_CHANNEL_ID = "ALR";
-
-    <T extends Plugin> T getOneShotPlugin(Class<T> cls);
-    <T extends Plugin> T getOneShotPlugin(String action, Class<?> cls);
-
-    <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls);
-    <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls,
-            boolean allowMultiple);
-    <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
-            Class<?> cls);
-    <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
-            Class cls, boolean allowMultiple);
-
-    void removePluginListener(PluginListener<?> listener);
-
-    <T> boolean dependsOn(Plugin p, Class<T> cls);
-
-    static <P> String getAction(Class<P> cls) {
-        ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class);
-        if (info == null) {
-            throw new RuntimeException(cls + " doesn't provide an interface");
-        }
-        if (TextUtils.isEmpty(info.action())) {
-            throw new RuntimeException(cls + " doesn't provide an action");
-        }
-        return info.action();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
deleted file mode 100644
index 2a17e35..0000000
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.app.Notification;
-import android.app.Notification.Action;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.Log.TerribleFailure;
-import android.util.Log.TerribleFailureHandler;
-import android.widget.Toast;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.systemui.Dependency;
-import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper;
-import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import dalvik.system.PathClassLoader;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.Map;
-
-/**
- * @see Plugin
- */
-public class PluginManagerImpl extends BroadcastReceiver implements PluginManager {
-
-    static final String DISABLE_PLUGIN = "com.android.systemui.action.DISABLE_PLUGIN";
-
-    private static PluginManager sInstance;
-
-    private final ArrayMap<PluginListener<?>, PluginInstanceManager> mPluginMap
-            = new ArrayMap<>();
-    private final Map<String, ClassLoader> mClassLoaders = new ArrayMap<>();
-    private final ArraySet<String> mOneShotPackages = new ArraySet<>();
-    private final Context mContext;
-    private final PluginInstanceManagerFactory mFactory;
-    private final boolean isDebuggable;
-    private final PluginPrefs mPluginPrefs;
-    private ClassLoaderFilter mParentClassLoader;
-    private boolean mListening;
-    private boolean mHasOneShot;
-    private Looper mLooper;
-    private boolean mWtfsSet;
-
-    public PluginManagerImpl(Context context) {
-        this(context, new PluginInstanceManagerFactory(),
-                Build.IS_DEBUGGABLE, Thread.getUncaughtExceptionPreHandler());
-    }
-
-    @VisibleForTesting
-    PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable,
-            UncaughtExceptionHandler defaultHandler) {
-        mContext = context;
-        mFactory = factory;
-        mLooper = Dependency.get(Dependency.BG_LOOPER);
-        isDebuggable = debuggable;
-        mPluginPrefs = new PluginPrefs(mContext);
-
-        PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler(
-                defaultHandler);
-        Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
-        if (isDebuggable) {
-            new Handler(mLooper).post(() -> {
-                // 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 <T extends Plugin> T getOneShotPlugin(Class<T> cls) {
-        ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class);
-        if (info == null) {
-            throw new RuntimeException(cls + " doesn't provide an interface");
-        }
-        if (TextUtils.isEmpty(info.action())) {
-            throw new RuntimeException(cls + " doesn't provide an action");
-        }
-        return getOneShotPlugin(info.action(), cls);
-    }
-
-    public <T extends Plugin> T getOneShotPlugin(String action, Class<?> cls) {
-        if (!isDebuggable) {
-            // Never ever ever allow these on production builds, they are only for prototyping.
-            return null;
-        }
-        if (Looper.myLooper() != Looper.getMainLooper()) {
-            throw new RuntimeException("Must be called from UI thread");
-        }
-        PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null,
-                false, mLooper, cls, this);
-        mPluginPrefs.addAction(action);
-        PluginInfo<T> info = p.getPlugin();
-        if (info != null) {
-            mOneShotPackages.add(info.mPackage);
-            mHasOneShot = true;
-            startListening();
-            return info.mPlugin;
-        }
-        return null;
-    }
-
-    public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls) {
-        addPluginListener(listener, cls, false);
-    }
-
-    public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls,
-            boolean allowMultiple) {
-        addPluginListener(PluginManager.getAction(cls), listener, cls, allowMultiple);
-    }
-
-    public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
-            Class<?> cls) {
-        addPluginListener(action, listener, cls, false);
-    }
-
-    public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
-            Class cls, boolean allowMultiple) {
-        if (!isDebuggable) {
-            // Never ever ever allow these on production builds, they are only for prototyping.
-            return;
-        }
-        mPluginPrefs.addAction(action);
-        PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener,
-                allowMultiple, mLooper, cls, this);
-        p.loadAll();
-        mPluginMap.put(listener, p);
-        startListening();
-    }
-
-    public void removePluginListener(PluginListener<?> listener) {
-        if (!isDebuggable) {
-            // Never ever ever allow these on production builds, they are only for prototyping.
-            return;
-        }
-        if (!mPluginMap.containsKey(listener)) return;
-        mPluginMap.remove(listener).destroy();
-        if (mPluginMap.size() == 0) {
-            stopListening();
-        }
-    }
-
-    private void startListening() {
-        if (mListening) return;
-        mListening = true;
-        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
-        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        filter.addAction(PLUGIN_CHANGED);
-        filter.addAction(DISABLE_PLUGIN);
-        filter.addDataScheme("package");
-        mContext.registerReceiver(this, filter);
-        filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiver(this, filter);
-    }
-
-    private void stopListening() {
-        // Never stop listening if a one-shot is present.
-        if (!mListening || mHasOneShot) return;
-        mListening = false;
-        mContext.unregisterReceiver(this);
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
-            for (PluginInstanceManager manager : mPluginMap.values()) {
-                manager.loadAll();
-            }
-        } else if (DISABLE_PLUGIN.equals(intent.getAction())) {
-            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);
-            mContext.getSystemService(NotificationManager.class).cancel(component.getClassName(),
-                    SystemMessage.NOTE_PLUGIN);
-        } else {
-            Uri data = intent.getData();
-            String pkg = data.getEncodedSchemeSpecificPart();
-            if (mOneShotPackages.contains(pkg)) {
-                int icon = mContext.getResources().getIdentifier("tuner", "drawable",
-                        mContext.getPackageName());
-                int color = Resources.getSystem().getIdentifier(
-                        "system_notification_accent_color", "color", "android");
-                String label = pkg;
-                try {
-                    PackageManager pm = mContext.getPackageManager();
-                    label = pm.getApplicationInfo(pkg, 0).loadLabel(pm).toString();
-                } catch (NameNotFoundException e) {
-                }
-                // Localization not required as this will never ever appear in a user build.
-                final Notification.Builder nb =
-                        new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
-                                .setSmallIcon(icon)
-                                .setWhen(0)
-                                .setShowWhen(false)
-                                .setPriority(Notification.PRIORITY_MAX)
-                                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                                .setColor(mContext.getColor(color))
-                                .setContentTitle("Plugin \"" + label + "\" has updated")
-                                .setContentText("Restart SysUI for changes to take effect.");
-                Intent i = new Intent("com.android.systemui.action.RESTART").setData(
-                            Uri.parse("package://" + pkg));
-                PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
-                nb.addAction(new Action.Builder(null, "Restart SysUI", pi).build());
-                mContext.getSystemService(NotificationManager.class).notifyAsUser(pkg,
-                        SystemMessage.NOTE_PLUGIN, nb.build(), UserHandle.ALL);
-            }
-            if (clearClassLoader(pkg)) {
-                Toast.makeText(mContext, "Reloading " + pkg, Toast.LENGTH_LONG).show();
-            }
-            if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
-                for (PluginInstanceManager manager : mPluginMap.values()) {
-                    manager.onPackageChange(pkg);
-                }
-            } else {
-                for (PluginInstanceManager manager : mPluginMap.values()) {
-                    manager.onPackageRemoved(pkg);
-                }
-            }
-        }
-    }
-
-    public ClassLoader getClassLoader(String sourceDir, String pkg) {
-        if (mClassLoaders.containsKey(pkg)) {
-            return mClassLoaders.get(pkg);
-        }
-        ClassLoader classLoader = new PathClassLoader(sourceDir, getParentClassLoader());
-        mClassLoaders.put(pkg, classLoader);
-        return classLoader;
-    }
-
-    private boolean clearClassLoader(String pkg) {
-        return mClassLoaders.remove(pkg) != null;
-    }
-
-    ClassLoader getParentClassLoader() {
-        if (mParentClassLoader == null) {
-            // Lazily load this so it doesn't have any effect on devices without plugins.
-            mParentClassLoader = new ClassLoaderFilter(getClass().getClassLoader(),
-                    "com.android.systemui.plugin");
-        }
-        return mParentClassLoader;
-    }
-
-    public Context getContext(ApplicationInfo info, String pkg) throws NameNotFoundException {
-        ClassLoader classLoader = getClassLoader(info.sourceDir, pkg);
-        return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
-    }
-
-    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
-        for (int i = 0; i < mPluginMap.size(); i++) {
-            if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void handleWtfs() {
-        if (!mWtfsSet) {
-            mWtfsSet = true;
-            Log.setWtfHandler((tag, what, system) -> {
-                throw new CrashWhilePluginActiveException(what);
-            });
-        }
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println(String.format("  plugin map (%d):", mPluginMap.size()));
-        for (PluginListener listener: mPluginMap.keySet()) {
-            pw.println(String.format("    %s -> %s",
-                    listener, mPluginMap.get(listener)));
-        }
-    }
-
-    @VisibleForTesting
-    public static class PluginInstanceManagerFactory {
-        public <T extends Plugin> PluginInstanceManager createPluginInstanceManager(Context context,
-                String action, PluginListener<T> listener, boolean allowMultiple, Looper looper,
-                Class<?> cls, PluginManagerImpl manager) {
-            return new PluginInstanceManager(context, action, listener, allowMultiple, looper,
-                    new VersionInfo().addClass(cls), manager);
-        }
-    }
-
-    // This allows plugins to include any libraries or copied code they want by only including
-    // classes from the plugin library.
-    private static class ClassLoaderFilter extends ClassLoader {
-        private final String mPackage;
-        private final ClassLoader mBase;
-
-        public ClassLoaderFilter(ClassLoader base, String pkg) {
-            super(ClassLoader.getSystemClassLoader());
-            mBase = base;
-            mPackage = pkg;
-        }
-
-        @Override
-        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-            if (!name.startsWith(mPackage)) super.loadClass(name, resolve);
-            return mBase.loadClass(name);
-        }
-    }
-
-    private class PluginExceptionHandler implements UncaughtExceptionHandler {
-        private final UncaughtExceptionHandler mHandler;
-
-        private PluginExceptionHandler(UncaughtExceptionHandler handler) {
-            mHandler = handler;
-        }
-
-        @Override
-        public void uncaughtException(Thread thread, Throwable throwable) {
-            if (SystemProperties.getBoolean("plugin.debugging", false)) {
-                mHandler.uncaughtException(thread, throwable);
-                return;
-            }
-            // Search for and disable plugins that may have been involved in this crash.
-            boolean disabledAny = checkStack(throwable);
-            if (!disabledAny) {
-                // We couldn't find any plugins involved in this crash, just to be safe
-                // disable all the plugins, so we can be sure that SysUI is running as
-                // best as possible.
-                for (PluginInstanceManager manager : mPluginMap.values()) {
-                    disabledAny |= manager.disableAll();
-                }
-            }
-            if (disabledAny) {
-                throwable = new CrashWhilePluginActiveException(throwable);
-            }
-
-            // Run the normal exception handler so we can crash and cleanup our state.
-            mHandler.uncaughtException(thread, throwable);
-        }
-
-        private boolean checkStack(Throwable throwable) {
-            if (throwable == null) return false;
-            boolean disabledAny = false;
-            for (StackTraceElement element : throwable.getStackTrace()) {
-                for (PluginInstanceManager manager : mPluginMap.values()) {
-                    disabledAny |= manager.checkAndDisable(element.getClassName());
-                }
-            }
-            return disabledAny | checkStack(throwable.getCause());
-        }
-    }
-
-    private class CrashWhilePluginActiveException extends RuntimeException {
-        public CrashWhilePluginActiveException(Throwable throwable) {
-            super(throwable);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginPrefs.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginPrefs.java
deleted file mode 100644
index 3671b3c..0000000
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginPrefs.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.ArraySet;
-
-import java.util.Set;
-
-/**
- * Storage for all plugin actions in SharedPreferences.
- *
- * This allows the list of actions that the Tuner needs to search for to be generated
- * instead of hard coded.
- */
-public class PluginPrefs {
-
-    private static final String PREFS = "plugin_prefs";
-
-    private static final String PLUGIN_ACTIONS = "actions";
-    private static final String HAS_PLUGINS = "plugins";
-
-    private final Set<String> mPluginActions;
-    private final SharedPreferences mSharedPrefs;
-
-    public PluginPrefs(Context context) {
-        mSharedPrefs = context.getSharedPreferences(PREFS, 0);
-        mPluginActions = new ArraySet<>(mSharedPrefs.getStringSet(PLUGIN_ACTIONS, null));
-    }
-
-    public Set<String> getPluginList() {
-        return mPluginActions;
-    }
-
-    public synchronized void addAction(String action) {
-        if (mPluginActions.add(action)){
-            mSharedPrefs.edit().putStringSet(PLUGIN_ACTIONS, mPluginActions).commit();
-        }
-    }
-
-    public static boolean hasPlugins(Context context) {
-        return context.getSharedPreferences(PREFS, 0).getBoolean(HAS_PLUGINS, false);
-    }
-
-    public static void setHasPlugins(Context context) {
-        context.getSharedPreferences(PREFS, 0).edit().putBoolean(HAS_PLUGINS, true).commit();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java b/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java
deleted file mode 100644
index facfd98..0000000
--- a/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import com.android.systemui.plugins.annotations.Dependencies;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.annotations.Requirements;
-import com.android.systemui.plugins.annotations.Requires;
-
-import android.util.ArrayMap;
-
-public class VersionInfo {
-
-    private final ArrayMap<Class<?>, Version> mVersions = new ArrayMap<>();
-    private Class<?> mDefault;
-
-    public boolean hasVersionInfo() {
-        return !mVersions.isEmpty();
-    }
-
-    public int getDefaultVersion() {
-        return mVersions.get(mDefault).mVersion;
-    }
-
-    public VersionInfo addClass(Class<?> cls) {
-        if (mDefault == null) {
-            // The legacy default version is from the first class we add.
-            mDefault = cls;
-        }
-        addClass(cls, false);
-        return this;
-    }
-
-    private void addClass(Class<?> cls, boolean required) {
-        if (mVersions.containsKey(cls)) return;
-        ProvidesInterface provider = cls.getDeclaredAnnotation(ProvidesInterface.class);
-        if (provider != null) {
-            mVersions.put(cls, new Version(provider.version(), true));
-        }
-        Requires requires = cls.getDeclaredAnnotation(Requires.class);
-        if (requires != null) {
-            mVersions.put(requires.target(), new Version(requires.version(), required));
-        }
-        Requirements requirements = cls.getDeclaredAnnotation(Requirements.class);
-        if (requirements != null) {
-            for (Requires r : requirements.value()) {
-                mVersions.put(r.target(), new Version(r.version(), required));
-            }
-        }
-        DependsOn depends = cls.getDeclaredAnnotation(DependsOn.class);
-        if (depends != null) {
-            addClass(depends.target(), true);
-        }
-        Dependencies dependencies = cls.getDeclaredAnnotation(Dependencies.class);
-        if (dependencies != null) {
-            for (DependsOn d : dependencies.value()) {
-                addClass(d.target(), true);
-            }
-        }
-    }
-
-    public void checkVersion(VersionInfo plugin) throws InvalidVersionException {
-        ArrayMap<Class<?>, Version> versions = new ArrayMap<>(mVersions);
-        plugin.mVersions.forEach((aClass, version) -> {
-            Version v = versions.remove(aClass);
-            if (v == null) {
-                v = createVersion(aClass);
-            }
-            if (v == null) {
-                throw new InvalidVersionException(aClass.getSimpleName()
-                        + " does not provide an interface", false);
-            }
-            if (v.mVersion != version.mVersion) {
-                throw new InvalidVersionException(aClass, v.mVersion < version.mVersion, v.mVersion,
-                        version.mVersion);
-            }
-        });
-        versions.forEach((aClass, version) -> {
-            if (version.mRequired) {
-                throw new InvalidVersionException("Missing required dependency "
-                        + aClass.getSimpleName(), false);
-            }
-        });
-    }
-
-    private Version createVersion(Class<?> cls) {
-        ProvidesInterface provider = cls.getDeclaredAnnotation(ProvidesInterface.class);
-        if (provider != null) {
-            return new Version(provider.version(), false);
-        }
-        return null;
-    }
-
-    public <T> boolean hasClass(Class<T> cls) {
-        return mVersions.containsKey(cls);
-    }
-
-    public static class InvalidVersionException extends RuntimeException {
-        private final boolean mTooNew;
-
-        public InvalidVersionException(String str, boolean tooNew) {
-            super(str);
-            mTooNew = tooNew;
-        }
-
-        public InvalidVersionException(Class<?> cls, boolean tooNew, int expected, int actual) {
-            super(cls.getSimpleName() + " expected version " + expected + " but had " + actual);
-            mTooNew = tooNew;
-        }
-
-        public boolean isTooNew() {
-            return mTooNew;
-        }
-    }
-
-    private static class Version {
-
-        private final int mVersion;
-        private final boolean mRequired;
-
-        public Version(int version, boolean required) {
-            mVersion = version;
-            mRequired = required;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 0b9067e..568a039 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -301,9 +301,10 @@
             // mark if we've already shown a warning this cycle. This will prevent the notification
             // trigger from spamming users by only showing low/critical warnings once per cycle
             if (hybridEnabled) {
-                if (mTimeRemaining < mEnhancedEstimates.getSevereWarningThreshold()
-                        || mBatteryLevel < mLowBatteryReminderLevels[1]) {
+                if (mTimeRemaining <= mEnhancedEstimates.getSevereWarningThreshold()
+                        || mBatteryLevel <= mLowBatteryReminderLevels[1]) {
                     mSevereWarningShownThisChargeCycle = true;
+                    mLowWarningShownThisChargeCycle = true;
                 } else {
                     mLowWarningShownThisChargeCycle = true;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 123fca7..76dfddb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -8,18 +8,20 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
+import android.graphics.Rect;
+import android.os.Bundle;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 import android.view.animation.OvershootInterpolator;
 import android.widget.Scroller;
 
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanel.TileRecord;
@@ -30,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;
@@ -41,14 +44,12 @@
         return t * t * t + 1.0f;
     };
 
-
     private final ArrayList<TileRecord> mTiles = new ArrayList<>();
     private final ArrayList<TilePage> mPages = new ArrayList<>();
 
     private PageIndicator mPageIndicator;
     private float mPageIndicatorPosition;
 
-    private int mNumPages;
     private PageListener mPageListener;
 
     private boolean mListening;
@@ -56,6 +57,11 @@
 
     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);
@@ -63,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
@@ -118,11 +148,12 @@
         super.onFinishInflate();
         mPages.add((TilePage) LayoutInflater.from(getContext())
                 .inflate(R.layout.qs_paged_page, this, false));
+        mAdapter.notifyDataSetChanged();
     }
 
     public void setPageIndicator(PageIndicator indicator) {
         mPageIndicator = indicator;
-        mPageIndicator.setNumPages(mNumPages);
+        mPageIndicator.setNumPages(mPages.size());
         mPageIndicator.setLocation(mPageIndicatorPosition);
     }
 
@@ -136,13 +167,15 @@
     @Override
     public void addTile(TileRecord tile) {
         mTiles.add(tile);
-        postDistributeTiles();
+        mDistributeTiles = true;
+        requestLayout();
     }
 
     @Override
     public void removeTile(TileRecord tile) {
         if (mTiles.remove(tile)) {
-            postDistributeTiles();
+            mDistributeTiles = true;
+            requestLayout();
         }
     }
 
@@ -175,43 +208,52 @@
         mPageListener = listener;
     }
 
-    private void postDistributeTiles() {
-        removeCallbacks(mDistribute);
-        post(mDistribute);
-    }
-
     private void distributeTiles() {
+        emptyAndInflateOrRemovePages();
+
+        final int tileCount = mPages.get(0).maxTiles();
         if (DEBUG) Log.d(TAG, "Distributing tiles");
-        final int NP = mPages.size();
-        for (int i = 0; i < NP; i++) {
-            mPages.get(i).removeAllViews();
-        }
         int index = 0;
         final int NT = mTiles.size();
         for (int i = 0; i < NT; i++) {
             TileRecord tile = mTiles.get(i);
-            if (mPages.get(index).isFull()) {
-                if (++index == mPages.size()) {
-                    if (DEBUG) Log.d(TAG, "Adding page for "
-                            + tile.tile.getClass().getSimpleName());
-                    mPages.add((TilePage) LayoutInflater.from(getContext())
-                            .inflate(R.layout.qs_paged_page, this, false));
-                }
+            if (mPages.get(index).mRecords.size() == tileCount) index++;
+            if (DEBUG) {
+                Log.d(TAG, "Adding " + tile.tile.getClass().getSimpleName() + " to "
+                        + index);
             }
-            if (DEBUG) Log.d(TAG, "Adding " + tile.tile.getClass().getSimpleName() + " to "
-                    + index);
             mPages.get(index).addTile(tile);
         }
-        if (mNumPages != index + 1) {
-            mNumPages = index + 1;
-            while (mPages.size() > mNumPages) {
-                mPages.remove(mPages.size() - 1);
-            }
-            if (DEBUG) Log.d(TAG, "Size: " + mNumPages);
-            mPageIndicator.setNumPages(mNumPages);
-            setAdapter(mAdapter);
-            mAdapter.notifyDataSetChanged();
-            setCurrentItem(0, false);
+    }
+
+    private void emptyAndInflateOrRemovePages() {
+        final int nTiles = mTiles.size();
+        int numPages = nTiles / mPages.get(0).maxTiles();
+        // Add one more not full page if needed
+        numPages += (nTiles % mPages.get(0).maxTiles() == 0 ? 0 : 1);
+
+        final int NP = mPages.size();
+        for (int i = 0; i < NP; i++) {
+            mPages.get(i).removeAllViews();
+        }
+        if (NP == numPages) {
+            return;
+        }
+        while (mPages.size() < numPages) {
+            if (DEBUG) Log.d(TAG, "Adding page");
+            mPages.add((TilePage) LayoutInflater.from(getContext())
+                    .inflate(R.layout.qs_paged_page, this, false));
+        }
+        while (mPages.size() > numPages) {
+            if (DEBUG) Log.d(TAG, "Removing page");
+            mPages.remove(mPages.size() - 1);
+        }
+        mPageIndicator.setNumPages(mPages.size());
+        setAdapter(mAdapter);
+        mAdapter.notifyDataSetChanged();
+        if (mPageToRestore != -1) {
+            setCurrentItem(mPageToRestore, false);
+            mPageToRestore = -1;
         }
     }
 
@@ -219,23 +261,51 @@
     public boolean updateResources() {
         // Update bottom padding, useful for removing extra space once the panel page indicator is
         // hidden.
+        Resources res = getContext().getResources();
+        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;
         for (int i = 0; i < mPages.size(); i++) {
             changed |= mPages.get(i).updateResources();
         }
         if (changed) {
-            distributeTiles();
+            mDistributeTiles = true;
+            requestLayout();
         }
         return changed;
     }
 
     @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();
+        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
+
+            // Only change the pages if the number of rows or columns (from updateResources) has
+            // changed or the tiles have changed
+            if (mPages.get(0).updateMaxRows(heightMeasureSpec, nTiles) || mDistributeTiles) {
+                mDistributeTiles = false;
+                distributeTiles();
+            }
+
+            final int nRows = mPages.get(0).mRows;
+            for (int i = 0; i < mPages.size(); i++) {
+                TilePage t = mPages.get(i);
+                t.mRows = nRows;
+            }
+        }
+
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
         // The ViewPager likes to eat all of the space, instead force it to wrap to the max height
         // of the pages.
         int maxHeight = 0;
@@ -249,13 +319,6 @@
         setMeasuredDimension(getMeasuredWidth(), maxHeight + getPaddingBottom());
     }
 
-    private final Runnable mDistribute = new Runnable() {
-        @Override
-        public void run() {
-            distributeTiles();
-        }
-    };
-
     public int getColumnCount() {
         if (mPages.size() == 0) return 0;
         return mPages.get(0).mColumns;
@@ -346,33 +409,25 @@
             };
 
     public static class TilePage extends TileLayout {
-        private int mMaxRows = 3;
+
         public TilePage(Context context, AttributeSet attrs) {
             super(context, attrs);
-            updateResources();
+        }
+
+        public boolean isFull() {
+            return mRecords.size() >= mColumns * mRows;
+        }
+
+        public int maxTiles() {
+            return mColumns * mRows;
         }
 
         @Override
         public boolean updateResources() {
-            final int rows = getRows();
-            boolean changed = rows != mMaxRows;
-            if (changed) {
-                mMaxRows = rows;
-                requestLayout();
-            }
-            return super.updateResources() || changed;
-        }
-
-        private int getRows() {
-            return Math.max(1, getResources().getInteger(R.integer.quick_settings_num_rows));
-        }
-
-        public void setMaxRows(int maxRows) {
-            mMaxRows = maxRows;
-        }
-
-        public boolean isFull() {
-            return mRecords.size() >= mColumns * mMaxRows;
+            final int sidePadding = getContext().getResources().getDimensionPixelSize(
+                    R.dimen.notification_side_paddings);
+            setPadding(sidePadding, 0, sidePadding, 0);
+            return super.updateResources();
         }
     }
 
@@ -401,7 +456,7 @@
 
         @Override
         public int getCount() {
-            return mNumPages;
+            return mPages.size();
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index feff5d4..1451e71 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -23,6 +23,7 @@
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
 import android.widget.FrameLayout;
 
@@ -91,15 +92,24 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Since we control our own bottom, be whatever size we want.
-        // Otherwise the QSPanel ends up with 0 height when the window is only the
-        // size of the status bar.
-        mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(
-                MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.UNSPECIFIED));
+        // QSPanel will show as many rows as it can (up to TileLayout.MAX_ROWS) such that the
+        // bottom and footer are inside the screen.
+        Configuration config = getResources().getConfiguration();
+        boolean navBelow = config.smallestScreenWidthDp >= 600
+                || config.orientation != Configuration.ORIENTATION_LANDSCAPE;
+        MarginLayoutParams layoutParams = (MarginLayoutParams) mQSPanel.getLayoutParams();
+
+        // The footer is pinned to the bottom of QSPanel (same bottoms), therefore we don't need to
+        // subtract its height. We do not care if the collapsed notifications fit in the screen.
+        int maxQs = getDisplayHeight() - layoutParams.topMargin - layoutParams.bottomMargin
+                - getPaddingBottom();
+        if (navBelow) {
+            maxQs -= getResources().getDimensionPixelSize(R.dimen.navigation_bar_height);
+        }
+        mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.AT_MOST));
         int width = mQSPanel.getMeasuredWidth();
-        LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams();
         int height = layoutParams.topMargin + layoutParams.bottomMargin
-                + mQSPanel.getMeasuredHeight();
+                + mQSPanel.getMeasuredHeight() + getPaddingBottom();
         super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index c36cdf6..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;
@@ -256,7 +261,7 @@
     public void setExpanded(boolean expanded) {
         if (DEBUG) Log.d(TAG, "setExpanded " + expanded);
         mQsExpanded = expanded;
-        mQSPanel.setListening(mListening && mQsExpanded);
+        mQSPanel.setListening(mListening, mQsExpanded);
         updateQsState();
     }
 
@@ -287,8 +292,7 @@
         mListening = listening;
         mHeader.setListening(listening);
         mFooter.setListening(listening);
-        mQSPanel.setListening(mListening && mQsExpanded);
-        mQSPanel.getFooter().setListening(listening);
+        mQSPanel.setListening(mListening, mQsExpanded);
     }
 
     @Override
@@ -365,7 +369,11 @@
                 .setListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
-                        getView().animate().setListener(null);
+                        if (getView() != null) {
+                            // The view could be destroyed before the animation completes when
+                            // switching users.
+                            getView().animate().setListener(null);
+                        }
                         mHeaderAnimating = false;
                         updateQsState();
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 7a57fdd..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;
@@ -199,7 +200,11 @@
 
     public void openDetails(String subPanel) {
         QSTile tile = getTile(subPanel);
-        showDetailAdapter(true, tile.getDetailAdapter(), new int[]{getWidth() / 2, 0});
+        // If there's no tile with that name (as defined in QSFactoryImpl or other QSFactory),
+        // QSFactory will not be able to create a tile and getTile will return null
+        if (tile != null) {
+            showDetailAdapter(true, tile.getDetailAdapter(), new int[]{getWidth() / 2, 0});
+        }
     }
 
     private QSTile getTile(String subPanel) {
@@ -353,12 +358,21 @@
         if (mListening) {
             refreshAllTiles();
         }
-        if (mBrightnessView.getVisibility() == View.VISIBLE) {
-            if (listening) {
-                mBrightnessController.registerCallbacks();
-            } else {
-                mBrightnessController.unregisterCallbacks();
-            }
+    }
+
+    public void setListening(boolean listening, boolean expanded) {
+        setListening(listening && expanded);
+        getFooter().setListening(listening);
+        // Set the listening as soon as the QS fragment starts listening regardless of the expansion,
+        // so it will update the current brightness before the slider is visible.
+        setBrightnessListening(listening);
+    }
+
+    public void setBrightnessListening(boolean listening) {
+        if (listening) {
+            mBrightnessController.registerCallbacks();
+        } else {
+            mBrightnessController.unregisterCallbacks();
         }
     }
 
@@ -653,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/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 86e69e3..cefeeb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -31,7 +31,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.qs.QSTileView;
 import com.android.systemui.plugins.qs.QSTile;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 556786a..6f847c8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -253,7 +253,8 @@
 
             final int availableWidth = getMeasuredWidth() - getPaddingStart() - getPaddingEnd();
             final int leftoverWithespace = availableWidth - maxTiles * mCellWidth;
-            final int smallestHorizontalMarginNeeded = leftoverWithespace / (maxTiles - 1);
+            final int smallestHorizontalMarginNeeded;
+            smallestHorizontalMarginNeeded = leftoverWithespace / Math.max(1, maxTiles - 1);
 
             if (smallestHorizontalMarginNeeded > 0){
                 mCellMarginHorizontal = smallestHorizontalMarginNeeded;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index c67165e..1dd729d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -24,10 +24,12 @@
     protected int mCellMarginHorizontal;
     protected int mCellMarginVertical;
     protected int mSidePadding;
+    protected int mRows = 1;
 
     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
     private int mCellMarginTop;
     private boolean mListening;
+    protected int mMaxAllowedRows = 3;
 
     public TileLayout(Context context) {
         this(context, null);
@@ -86,6 +88,7 @@
         mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
         mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
         mSidePadding = res.getDimensionPixelOffset(R.dimen.qs_tile_layout_margin_side);
+        mMaxAllowedRows = Math.max(1, getResources().getInteger(R.integer.quick_settings_max_rows));
         if (mColumns != columns) {
             mColumns = columns;
             requestLayout();
@@ -96,11 +99,18 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // If called with AT_MOST, it will limit the number of rows. If called with UNSPECIFIED
+        // it will show all its tiles. In this case, the tiles have to be entered before the
+        // container is measured. Any change in the tiles, should trigger a remeasure.
         final int numTiles = mRecords.size();
-        final int width = MeasureSpec.getSize(widthMeasureSpec)
-                - getPaddingStart() - getPaddingEnd();
-        final int numRows = (numTiles + mColumns - 1) / mColumns;
-        mCellWidth = (width - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
+        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 =
+                (availableWidth - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
 
         // Measure each QS tile.
         View previousView = this;
@@ -112,11 +122,33 @@
 
         // Only include the top margin in our measurement if we have more than 1 row to show.
         // Otherwise, don't add the extra margin buffer at top.
-        int height = (mCellHeight + mCellMarginVertical) * numRows +
-                (numRows != 0 ? (mCellMarginTop - mCellMarginVertical) : 0);
+        int height = (mCellHeight + mCellMarginVertical) * mRows +
+                (mRows != 0 ? (mCellMarginTop - mCellMarginVertical) : 0);
         if (height < 0) height = 0;
 
-        setMeasuredDimension(width, height);
+        setMeasuredDimension(width + getPaddingStart() + getPaddingEnd(), height);
+    }
+
+    /**
+     * Determines the maximum number of rows that can be shown based on height. Clips at a minimum
+     * of 1 and a maximum of mMaxAllowedRows.
+     *
+     * @param heightMeasureSpec Available height.
+     * @param tilesCount Upper limit on the number of tiles to show. to prevent empty rows.
+     */
+    public boolean updateMaxRows(int heightMeasureSpec, int tilesCount) {
+        final int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mCellMarginTop;
+        final int previousRows = mRows;
+        mRows = availableHeight / (mCellHeight + mCellMarginVertical);
+        if (mRows >= mMaxAllowedRows) {
+            mRows = mMaxAllowedRows;
+        } else if (mRows <= 1) {
+            mRows = 1;
+        }
+        if (mRows > (tilesCount + mColumns - 1) / mColumns) {
+            mRows = (tilesCount + mColumns - 1) / mColumns;
+        }
+        return previousRows != mRows;
     }
 
     @Override
@@ -135,7 +167,8 @@
         int column = 0;
 
         // Layout each QS tile.
-        for (int i = 0; i < numRecords; i++, column++) {
+        final int tilesToLayout = Math.min(numRecords, mRows * mColumns);
+        for (int i = 0; i < tilesToLayout; i++, column++) {
             // If we reached the last column available to layout a tile, wrap back to the next row.
             if (column == mColumns) {
                 column = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 3f7eeb8..dc17dd8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -69,6 +69,7 @@
     private final QSDetailClipper mClipper;
     private final LightBarController mLightBarController;
     private final TileQueryHelper mTileQueryHelper;
+    private final View mTransparentView;
 
     private boolean isShown;
     private QSTileHost mHost;
@@ -108,6 +109,7 @@
         mToolbar.getNavigationIcon().setTint(accentColor);
         mToolbar.getOverflowIcon().setTint(accentColor);
         mRecyclerView = findViewById(android.R.id.list);
+        mTransparentView = findViewById(R.id.customizer_transparent_view);
         mTileAdapter = new TileAdapter(getContext());
         mTileQueryHelper = new TileQueryHelper(context, mTileAdapter);
         mRecyclerView.setAdapter(mTileAdapter);
@@ -127,6 +129,14 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         updateNavBackDrop(newConfig);
+        updateResources();
+    }
+
+    private void updateResources() {
+        LayoutParams lp = (LayoutParams) mTransparentView.getLayoutParams();
+        lp.height = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.quick_qs_offset_height);
+        mTransparentView.setLayoutParams(lp);
     }
 
     private void updateNavBackDrop(Configuration newConfig) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 12daff1..9edd65e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -25,6 +25,7 @@
 import android.graphics.drawable.Drawable;
 import android.nfc.NfcAdapter;
 import android.provider.Settings;
+import android.service.quicksettings.Tile;
 import android.widget.Switch;
 
 import com.android.internal.logging.MetricsLogger;
@@ -77,6 +78,9 @@
 
     @Override
     protected void handleClick() {
+        if (getAdapter() == null) {
+            return;
+        }
         if (!getAdapter().isEnabled()) {
             getAdapter().enable();
         } else {
@@ -96,13 +100,13 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        final Drawable mEnable = mContext.getDrawable(R.drawable.ic_qs_nfc_enabled);
-        final Drawable mDisable = mContext.getDrawable(R.drawable.ic_qs_nfc_disabled);
-
-        if (getAdapter() == null) return;
-        state.value = getAdapter().isEnabled();
+        state.value = getAdapter() != null && getAdapter().isEnabled();
+        state.state = getAdapter() == null
+                ? Tile.STATE_UNAVAILABLE
+                : state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.icon = ResourceIcon.get(
+                state.value ? R.drawable.ic_qs_nfc_enabled : R.drawable.ic_qs_nfc_disabled);
         state.label = mContext.getString(R.string.quick_settings_nfc_label);
-        state.icon = new DrawableIcon(state.value ? mEnable : mDisable);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
index fc1831d..90c1099 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
@@ -31,8 +31,7 @@
     void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
     void toggleRecents(int recentsGrowTarget);
     void onConfigurationChanged();
-    void splitPrimaryTask(int topTaskId, int dragMode, int stackCreateMode,
-            in Rect initialBounds);
+    void splitPrimaryTask(int topTaskId, int stackCreateMode, in Rect initialBounds);
     void onDraggingInRecents(float distanceFromTop);
     void onDraggingInRecentsEnded(float velocity);
     void showCurrentUserToast(int msgResId, int msgLength);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
index 58d8d8f..e977144 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
@@ -29,7 +29,7 @@
     void updateRecentsVisibility(boolean visible);
     void startScreenPinning(int taskId);
     void sendRecentsDrawnEvent();
-    void sendDockingTopTaskEvent(int dragMode, in Rect initialRect);
+    void sendDockingTopTaskEvent(in Rect initialRect);
     void sendLaunchRecentsEvent();
     void sendDockedFirstAnimationFrameEvent();
     void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 8bb3c02..74f6c2d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -53,6 +53,7 @@
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.SystemUI;
 import com.android.systemui.recents.events.EventBus;
@@ -248,6 +249,10 @@
         mImpl.onBootCompleted();
     }
 
+    public void growRecents() {
+        EventBus.getDefault().send(new RecentsGrowingEvent());
+    }
+
     /**
      * Shows the Recents.
      */
@@ -463,7 +468,7 @@
     }
 
     @Override
-    public boolean splitPrimaryTask(int dragMode, int stackCreateMode, Rect initialBounds,
+    public boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
             int metricsDockAction) {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
@@ -495,16 +500,15 @@
                             runningTask.topActivity.flattenToShortString());
                 }
                 if (sSystemServicesProxy.isSystemUser(currentUser)) {
-                    mImpl.splitPrimaryTask(runningTask.id, dragMode, stackCreateMode,
-                            initialBounds);
+                    mImpl.splitPrimaryTask(runningTask.id, stackCreateMode, initialBounds);
                 } else {
                     if (mSystemToUserCallbacks != null) {
                         IRecentsNonSystemUserCallbacks callbacks =
                                 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                         if (callbacks != null) {
                             try {
-                                callbacks.splitPrimaryTask(runningTask.id, dragMode,
-                                        stackCreateMode, initialBounds);
+                                callbacks.splitPrimaryTask(runningTask.id, stackCreateMode,
+                                        initialBounds);
                             } catch (RemoteException e) {
                                 Log.e(TAG, "Callback failed", e);
                             }
@@ -552,53 +556,6 @@
         }
     }
 
-    @Override
-    public void onDraggingInRecents(float distanceFromTop) {
-        if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
-            mImpl.onDraggingInRecents(distanceFromTop);
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
-                                mDraggingInRecentsCurrentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.onDraggingInRecents(distanceFromTop);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: "
-                            + mDraggingInRecentsCurrentUser);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onDraggingInRecentsEnded(float velocity) {
-        if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
-            mImpl.onDraggingInRecentsEnded(velocity);
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
-                                mDraggingInRecentsCurrentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.onDraggingInRecentsEnded(velocity);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: "
-                            + mDraggingInRecentsCurrentUser);
-                }
-            }
-        }
-    }
-
-    @Override
     public void showNextAffiliatedTask() {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
@@ -609,7 +566,6 @@
         mImpl.showNextAffiliatedTask();
     }
 
-    @Override
     public void showPrevAffiliatedTask() {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
@@ -686,7 +642,12 @@
     public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         int processUser = ssp.getProcessUser();
-        if (!ssp.isSystemUser(processUser)) {
+        if (ssp.isSystemUser(processUser)) {
+            final Divider divider = getComponent(Divider.class);
+            if (divider != null) {
+                divider.onDockedFirstAnimationFrame();
+            }
+        } else {
             postToSystemUser(new Runnable() {
                 @Override
                 public void run() {
@@ -723,7 +684,12 @@
 
     public final void onBusEvent(final RecentsDrawnEvent event) {
         int processUser = sSystemServicesProxy.getProcessUser();
-        if (!sSystemServicesProxy.isSystemUser(processUser)) {
+        if (sSystemServicesProxy.isSystemUser(processUser)) {
+            final Divider divider = getComponent(Divider.class);
+            if (divider != null) {
+                divider.onRecentsDrawn();
+            }
+        } else {
             postToSystemUser(new Runnable() {
                 @Override
                 public void run() {
@@ -739,13 +705,17 @@
 
     public final void onBusEvent(final DockedTopTaskEvent event) {
         int processUser = sSystemServicesProxy.getProcessUser();
-        if (!sSystemServicesProxy.isSystemUser(processUser)) {
+        if (sSystemServicesProxy.isSystemUser(processUser)) {
+            final Divider divider = getComponent(Divider.class);
+            if (divider != null) {
+                divider.onDockedTopTask();
+            }
+        } else {
             postToSystemUser(new Runnable() {
                 @Override
                 public void run() {
                     try {
-                        mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode,
-                                event.initialRect);
+                        mUserToSystemCallbacks.sendDockingTopTaskEvent(event.initialRect);
                     } catch (RemoteException e) {
                         Log.e(TAG, "Callback failed", e);
                     }
@@ -756,7 +726,12 @@
 
     public final void onBusEvent(final RecentsActivityStartingEvent event) {
         int processUser = sSystemServicesProxy.getProcessUser();
-        if (!sSystemServicesProxy.isSystemUser(processUser)) {
+        if (sSystemServicesProxy.isSystemUser(processUser)) {
+            final Divider divider = getComponent(Divider.class);
+            if (divider != null) {
+                divider.onRecentsActivityStarting();
+            }
+        } else {
             postToSystemUser(new Runnable() {
                 @Override
                 public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 63a65d0..d95c731 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -49,6 +49,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.OverviewProxyService;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.pip.phone.ForegroundThread;
 import com.google.android.collect.Lists;
 
 import com.android.internal.logging.MetricsLogger;
@@ -72,7 +73,6 @@
 import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
 import com.android.systemui.recents.events.ui.TaskSnapshotChangedEvent;
 import com.android.systemui.recents.misc.DozeTrigger;
-import com.android.systemui.recents.misc.ForegroundThread;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
@@ -690,14 +690,13 @@
         showRelativeAffiliatedTask(false);
     }
 
-    public void splitPrimaryTask(int taskId, int dragMode, int stackCreateMode,
-            Rect initialBounds) {
+    public void splitPrimaryTask(int taskId, int stackCreateMode, Rect initialBounds) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Make sure we inform DividerView before we actually start the activity so we can change
         // the resize mode already.
         if (ssp.setTaskWindowingModeSplitScreenPrimary(taskId, stackCreateMode, initialBounds)) {
-            EventBus.getDefault().send(new DockedTopTaskEvent(dragMode, initialBounds));
+            EventBus.getDefault().send(new DockedTopTaskEvent(initialBounds));
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
index beec4b3..a1da785 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
@@ -87,12 +87,11 @@
     }
 
     @Override
-    public void splitPrimaryTask(int topTaskId, int dragMode, int stackCreateMode,
-            Rect initialBounds) throws RemoteException {
+    public void splitPrimaryTask(int topTaskId, int stackCreateMode, Rect initialBounds)
+            throws RemoteException {
         SomeArgs args = SomeArgs.obtain();
         args.argi1 = topTaskId;
-        args.argi2 = dragMode;
-        args.argi3 = stackCreateMode;
+        args.argi2 = stackCreateMode;
         args.arg1 = initialBounds;
         mHandler.sendMessage(mHandler.obtainMessage(MSG_DOCK_TOP_TASK, args));
     }
@@ -141,7 +140,7 @@
                     break;
                 case MSG_DOCK_TOP_TASK:
                     args = (SomeArgs) msg.obj;
-                    mImpl.splitPrimaryTask(args.argi1, args.argi2, args.argi3 = 0,
+                    mImpl.splitPrimaryTask(args.argi1, args.argi2 = 0,
                             (Rect) args.arg1);
                     break;
                 case MSG_ON_DRAGGING_IN_RECENTS:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index ff1f7dc..c5e9f04 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -26,13 +26,13 @@
 
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
+import com.android.systemui.pip.phone.ForegroundThread;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
-import com.android.systemui.recents.misc.ForegroundThread;
 
 /**
  * An implementation of the system user's Recents interface to be called remotely by secondary
@@ -99,8 +99,8 @@
     }
 
     @Override
-    public void sendDockingTopTaskEvent(int dragMode, Rect initialRect) throws RemoteException {
-        EventBus.getDefault().post(new DockedTopTaskEvent(dragMode, initialRect));
+    public void sendDockingTopTaskEvent(Rect initialRect) throws RemoteException {
+        EventBus.getDefault().post(new DockedTopTaskEvent(initialRect));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java
index f1bc214..9e3ced3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java
@@ -26,11 +26,9 @@
  */
 public class DockedTopTaskEvent extends EventBus.Event {
 
-    public int dragMode;
     public Rect initialRect;
 
-    public DockedTopTaskEvent(int dragMode, Rect initialRect) {
-        this.dragMode = dragMode;
+    public DockedTopTaskEvent(Rect initialRect) {
         this.initialRect = initialRect;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java
deleted file mode 100644
index 784ac4e..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.misc;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-
-/**
- * Similar to {@link com.android.internal.os.BackgroundThread}, this is a shared singleton
- * foreground thread for each process.
- */
-public final class ForegroundThread extends HandlerThread {
-    private static ForegroundThread sInstance;
-    private static Handler sHandler;
-
-    private ForegroundThread() {
-        super("recents.fg");
-    }
-
-    private static void ensureThreadLocked() {
-        if (sInstance == null) {
-            sInstance = new ForegroundThread();
-            sInstance.start();
-            sHandler = new Handler(sInstance.getLooper());
-        }
-    }
-
-    public static ForegroundThread get() {
-        synchronized (ForegroundThread.class) {
-            ensureThreadLocked();
-            return sInstance;
-        }
-    }
-
-    public static Handler getHandler() {
-        synchronized (ForegroundThread.class) {
-            ensureThreadLocked();
-            return sHandler;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 1178725..3ed5f70 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -460,7 +460,7 @@
 
     private void animateSliderTo(int target) {
         if (!mControlValueInitialized) {
-            // Don't animate the first value since it's default state isn't meaningful to users.
+            // Don't animate the first value since its default state isn't meaningful to users.
             mControl.setValue(target);
             mControlValueInitialized = true;
         }
@@ -470,10 +470,12 @@
         mSliderAnimator = ValueAnimator.ofInt(mControl.getValue(), target);
         mSliderAnimator.addUpdateListener((ValueAnimator animation) -> {
             mExternalChange = true;
-            mControl.setValue((int)animation.getAnimatedValue());
+            mControl.setValue((int) animation.getAnimatedValue());
             mExternalChange = false;
         });
-        mSliderAnimator.setDuration(SLIDER_ANIMATION_DURATION);
+        final long animationDuration = SLIDER_ANIMATION_DURATION * Math.abs(
+                mControl.getValue() - target) / GAMMA_SPACE_MAX;
+        mSliderAnimator.setDuration(animationDuration);
         mSliderAnimator.start();
     }
 
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/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 750002c..64fa8f8 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -18,11 +18,7 @@
 
 import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
 import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-import static android.os.UserHandle.USER_CURRENT;
 
-import static com.android.systemui.statusbar.phone.NavigationBarGestureHelper.DRAG_MODE_NONE;
-
-import android.app.ActivityManager;
 import android.content.res.Configuration;
 import android.os.RemoteException;
 import android.util.Log;
@@ -30,17 +26,11 @@
 import android.view.KeyEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
-
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.systemui.SystemUI;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.DividerView;
-import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
-
-import java.util.List;
 
 /**
  * Dispatches shortcut to System UI components
@@ -94,7 +84,7 @@
             if (dockSide == WindowManager.DOCKED_INVALID) {
                 // Split the screen
                 Recents recents = getComponent(Recents.class);
-                recents.splitPrimaryTask(DRAG_MODE_NONE, (shortcutCode == SC_DOCK_LEFT)
+                recents.splitPrimaryTask((shortcutCode == SC_DOCK_LEFT)
                         ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
                         : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index da0a435..ea194a7 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -16,29 +16,28 @@
 
 package com.android.systemui.stackdivider;
 
-import android.content.res.Configuration;
-import android.os.RemoteException;
-import android.view.IDockedStackListener;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
+import android.content.res.Configuration;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.IDockedStackListener;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManagerGlobal;
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.recents.Recents;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
 /**
  * Controls the docked stack divider.
  */
-public class Divider extends SystemUI {
+public class Divider extends SystemUI implements DividerView.DividerCallbacks {
+    private static final String TAG = "Divider";
+
     private DividerWindowManager mWindowManager;
     private DividerView mView;
     private final DividerState mDividerState = new DividerState();
@@ -55,10 +54,13 @@
         update(mContext.getResources().getConfiguration());
         putComponent(Divider.class, this);
         mDockDividerVisibilityListener = new DockDividerVisibilityListener();
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        ssp.registerDockedStackListener(mDockDividerVisibilityListener);
+        try {
+            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
+                    mDockDividerVisibilityListener);
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to register docked stack listener", e);
+        }
         mForcedResizableController = new ForcedResizableInfoActivityController(mContext);
-        EventBus.getDefault().register(this);
     }
 
     @Override
@@ -82,7 +84,7 @@
     private void addDivider(Configuration configuration) {
         mView = (DividerView)
                 LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
-        mView.injectDependencies(mWindowManager, mDividerState);
+        mView.injectDependencies(mWindowManager, mDividerState, this);
         mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
         mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
         final int size = mContext.getResources().getDimensionPixelSize(
@@ -156,18 +158,64 @@
         mWindowManager.setTouchable((mHomeStackResizable || !mMinimized) && !mAdjustedForIme);
     }
 
+    public void onRecentsActivityStarting() {
+        if (mView != null) {
+            mView.onRecentsActivityStarting();
+        }
+    }
+
     /**
-     * Workaround for b/62528361, at the time RecentsDrawnEvent is sent, it may happen before a
+     * Workaround for b/62528361, at the time recents has drawn, it may happen before a
      * configuration change to the Divider, and internally, the event will be posted to the
      * subscriber, or DividerView, which has been removed and prevented from resizing. Instead,
      * register the event handler here and proxy the event to the current DividerView.
      */
-    public final void onBusEvent(RecentsDrawnEvent drawnEvent) {
+    public void onRecentsDrawn() {
         if (mView != null) {
             mView.onRecentsDrawn();
         }
     }
 
+    public void onUndockingTask() {
+        if (mView != null) {
+            mView.onUndockingTask();
+        }
+    }
+
+    public void onDockedFirstAnimationFrame() {
+        if (mView != null) {
+            mView.onDockedFirstAnimationFrame();
+        }
+    }
+
+    public void onDockedTopTask() {
+        if (mView != null) {
+            mView.onDockedTopTask();
+        }
+    }
+
+    public void onAppTransitionFinished() {
+        mForcedResizableController.onAppTransitionFinished();
+    }
+
+    @Override
+    public void onDraggingStart() {
+        mForcedResizableController.onDraggingStart();
+    }
+
+    @Override
+    public void onDraggingEnd() {
+        mForcedResizableController.onDraggingEnd();
+    }
+
+    @Override
+    public void growRecents() {
+        Recents recents = getComponent(Recents.class);
+        if (recents != null) {
+            recents.growRecents();
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("  mVisible="); pw.println(mVisible);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 98925b9..fa01af6 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -55,7 +55,6 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.policy.DividerSnapAlgorithm;
@@ -64,17 +63,8 @@
 import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
-import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.events.activity.UndockingTaskEvent;
-import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.stackdivider.events.StartedDragingEvent;
-import com.android.systemui.stackdivider.events.StoppedDragingEvent;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.statusbar.FlingAnimationUtils;
-import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
 
 /**
  * Docked stack divider.
@@ -82,6 +72,12 @@
 public class DividerView extends FrameLayout implements OnTouchListener,
         OnComputeInternalInsetsListener {
 
+    public interface DividerCallbacks {
+        void onDraggingStart();
+        void onDraggingEnd();
+        void growRecents();
+    }
+
     static final long TOUCH_ANIMATION_DURATION = 150;
     static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
 
@@ -149,6 +145,7 @@
     private FlingAnimationUtils mFlingAnimationUtils;
     private DividerSnapAlgorithm mSnapAlgorithm;
     private DividerSnapAlgorithm mMinimizedSnapAlgorithm;
+    private DividerCallbacks mCallback;
     private final Rect mStableInsets = new Rect();
 
     private boolean mGrowRecents;
@@ -162,6 +159,7 @@
     private DividerState mState;
     private final SurfaceFlingerVsyncChoreographer mSfChoreographer;
 
+
     // The view is removed or in the process of been removed from the system.
     private boolean mRemoved;
 
@@ -306,7 +304,6 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        EventBus.getDefault().register(this);
 
         // Save the current target if not minimized once attached to window
         if (mHomeStackResizable && mDockSide != WindowManager.DOCKED_INVALID
@@ -315,14 +312,9 @@
         }
     }
 
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        EventBus.getDefault().unregister(this);
-    }
-
     void onDividerRemoved() {
         mRemoved = true;
+        mCallback = null;
         mHandler.removeMessages(MSG_RESIZE_STACK);
     }
 
@@ -364,13 +356,15 @@
         }
     }
 
-    public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState) {
+    public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState,
+            DividerCallbacks callback) {
         mWindowManager = windowManager;
         mState = dividerState;
+        mCallback = callback;
 
         // Set the previous position ratio before minimized state after attaching this divider
         if (mStableInsets.isEmpty()) {
-            SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+            WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
         }
 
         if (mState.mRatioPositionBeforeMinimized == 0) {
@@ -419,7 +413,9 @@
             mWindowManager.setSlippery(false);
             liftBackground();
         }
-        EventBus.getDefault().send(new StartedDragingEvent());
+        if (mCallback != null) {
+            mCallback.onDraggingStart();
+        }
         return mDockSide != WindowManager.DOCKED_INVALID;
     }
 
@@ -617,7 +613,9 @@
             mCurrentAnimator = null;
             mEntranceAnimationRunning = false;
             mExitAnimationRunning = false;
-            EventBus.getDefault().send(new StoppedDragingEvent());
+            if (mCallback != null) {
+                mCallback.onDraggingEnd();
+            }
 
             // Record last snap target the divider moved to
             if (mHomeStackResizable && !mIsInMinimizeInteraction) {
@@ -776,7 +774,7 @@
             if (mDisplayRotation != mDefaultDisplay.getRotation()) {
                 // Splitscreen to minimize is about to starts after rotating landscape to seascape,
                 // update insets, display info and snap algorithm targets
-                SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+                WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
                 repositionSnapTargetBeforeMinimized();
                 updateDisplayInfo();
             } else {
@@ -910,7 +908,7 @@
         requestLayout();
 
         // Update the snap position to the new docked side with correct insets
-        SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+        WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
         mMinimizedSnapAlgorithm = null;
         initializeSnapAlgorithm();
 
@@ -1271,7 +1269,7 @@
         }
     }
 
-    public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) {
+    void onRecentsActivityStarting() {
         if (mGrowRecents && mDockSide == WindowManager.DOCKED_TOP
                 && getSnapAlgorithm().getMiddleTarget() != getSnapAlgorithm().getLastSplitTarget()
                 && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) {
@@ -1280,16 +1278,14 @@
         }
     }
 
-    public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
+    void onDockedFirstAnimationFrame() {
         saveSnapTargetBeforeMinimized(mSnapAlgorithm.getMiddleTarget());
     }
 
-    public final void onBusEvent(DockedTopTaskEvent event) {
-        if (event.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) {
-            mState.growAfterRecentsDrawn = false;
-            mState.animateAfterRecentsDrawn = true;
-            startDragging(false /* animate */, false /* touching */);
-        }
+    void onDockedTopTask() {
+        mState.growAfterRecentsDrawn = false;
+        mState.animateAfterRecentsDrawn = true;
+        startDragging(false /* animate */, false /* touching */);
         updateDockSide();
         mEntranceAnimationRunning = true;
 
@@ -1297,7 +1293,7 @@
                 mSnapAlgorithm.getMiddleTarget());
     }
 
-    public void onRecentsDrawn() {
+    void onRecentsDrawn() {
         updateDockSide();
         final int position = calculatePositionForInsetBounds();
         if (mState.animateAfterRecentsDrawn) {
@@ -1314,13 +1310,15 @@
         if (mState.growAfterRecentsDrawn) {
             mState.growAfterRecentsDrawn = false;
             updateDockSide();
-            EventBus.getDefault().send(new RecentsGrowingEvent());
+            if (mCallback != null) {
+                mCallback.growRecents();
+            }
             stopDragging(position, getSnapAlgorithm().getMiddleTarget(), 336,
                     Interpolators.FAST_OUT_SLOW_IN);
         }
     }
 
-    public final void onBusEvent(UndockingTaskEvent undockingTaskEvent) {
+    void onUndockingTask() {
         int dockSide = mWindowManagerProxy.getDockSide();
         if (dockSide != WindowManager.DOCKED_INVALID && (mHomeStackResizable
                 || !mDockedStackMinimized)) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
index 4415bd7..02f7505 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
@@ -52,7 +52,7 @@
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.forced_resizable_activity);
-        TextView tv = (TextView) findViewById(com.android.internal.R.id.message);
+        TextView tv = findViewById(com.android.internal.R.id.message);
         int reason = getIntent().getIntExtra(EXTRA_FORCED_RESIZEABLE_REASON, -1);
         String text;
         switch (reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index 826fa6c..f66db48 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -16,8 +16,7 @@
 
 package com.android.systemui.stackdivider;
 
-import static com.android.systemui.stackdivider.ForcedResizableInfoActivity
-        .EXTRA_FORCED_RESIZEABLE_REASON;
+import static com.android.systemui.stackdivider.ForcedResizableInfoActivity.EXTRA_FORCED_RESIZEABLE_REASON;
 
 import android.app.ActivityOptions;
 import android.content.Context;
@@ -26,16 +25,9 @@
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.widget.Toast;
-
 import com.android.systemui.R;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
-import com.android.systemui.recents.events.component.ShowUserToastEvent;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.events.StartedDragingEvent;
-import com.android.systemui.stackdivider.events.StoppedDragingEvent;
+import com.android.systemui.shared.system.TaskStackChangeListener;
 
 /**
  * Controller that decides when to show the {@link ForcedResizableInfoActivity}.
@@ -49,7 +41,7 @@
     private final Handler mHandler = new Handler();
     private final ArraySet<PendingTaskRecord> mPendingTasks = new ArraySet<>();
     private final ArraySet<String> mPackagesShownInSession = new ArraySet<>();
-    private boolean mDividerDraging;
+    private boolean mDividerDragging;
 
     private final Runnable mTimeoutRunnable = new Runnable() {
         @Override
@@ -75,9 +67,8 @@
 
     public ForcedResizableInfoActivityController(Context context) {
         mContext = context;
-        EventBus.getDefault().register(this);
         ActivityManagerWrapper.getInstance().registerTaskStackListener(
-                new SysUiTaskStackChangeListener() {
+                new TaskStackChangeListener() {
                     @Override
                     public void onActivityForcedResizable(String packageName, int taskId,
                             int reason) {
@@ -102,19 +93,19 @@
         }
     }
 
-    public final void onBusEvent(AppTransitionFinishedEvent event) {
-        if (!mDividerDraging) {
+    public void onAppTransitionFinished() {
+        if (!mDividerDragging) {
             showPending();
         }
     }
 
-    public final void onBusEvent(StartedDragingEvent event) {
-        mDividerDraging = true;
+    void onDraggingStart() {
+        mDividerDragging = true;
         mHandler.removeCallbacks(mTimeoutRunnable);
     }
 
-    public final void onBusEvent(StoppedDragingEvent event) {
-        mDividerDraging = false;
+    void onDraggingEnd() {
+        mDividerDragging = false;
         showPending();
     }
 
@@ -127,13 +118,13 @@
     }
 
     private void activityDismissingDockedStack() {
-        EventBus.getDefault().send(new ShowUserToastEvent(
-                R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
+        Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
+                Toast.LENGTH_SHORT).show();
     }
 
     private void activityLaunchOnSecondaryDisplayFailed() {
-        EventBus.getDefault().send(new ShowUserToastEvent(
-                R.string.activity_launch_on_secondary_display_failed_text, Toast.LENGTH_SHORT));
+        Toast.makeText(mContext, R.string.activity_launch_on_secondary_display_failed_text,
+                Toast.LENGTH_SHORT).show();
     }
 
     private void showPending() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
deleted file mode 100644
index 5d19851..0000000
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.stackdivider.events;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when the divider is being draged either manually or by an animation.
- */
-public class StartedDragingEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
deleted file mode 100644
index c50d6d6..0000000
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.stackdivider.events;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when the divider isn't draging anymore.
- */
-public class StoppedDragingEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
index 4516518..b6e88d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
@@ -165,7 +165,7 @@
      * Whether or not the given notification is alerting and managed by this manager.
      * @return true if the notification is alerting
      */
-    public boolean contains(@NonNull String key) {
+    public boolean isAlerting(@NonNull String key) {
         return mAlertEntries.containsKey(key);
     }
 
@@ -294,7 +294,7 @@
             removeAutoRemovalCallbacks();
 
             if (!isSticky()) {
-                long finishTime = mPostTime + mAutoDismissNotificationDecay;
+                long finishTime = calculateFinishTime();
                 long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
                 mHandler.postDelayed(mRemoveAlertRunnable, removeDelay);
             }
@@ -357,6 +357,14 @@
         protected long calculatePostTime() {
             return mClock.currentTimeMillis();
         }
+
+        /**
+         * Calculate when the notification should auto-dismiss itself.
+         * @return the finish time
+         */
+        protected long calculateFinishTime() {
+            return mPostTime + mAutoDismissNotificationDecay;
+        }
     }
 
     protected final static class Clock {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
new file mode 100644
index 0000000..2c384d0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.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.statusbar;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.NotificationData;
+
+/**
+ * Manager which handles high priority notifications that should "pulse" in when the device is
+ * dozing and/or in AOD.  The pulse uses the notification's ambient view and pops in briefly
+ * before automatically dismissing the alert.
+ */
+public final class AmbientPulseManager extends AlertingNotificationManager {
+
+    protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>();
+    @VisibleForTesting
+    protected long mExtensionTime;
+
+    public AmbientPulseManager(@NonNull final Context context) {
+        Resources resources = context.getResources();
+        mAutoDismissNotificationDecay = resources.getInteger(R.integer.ambient_notification_decay);
+        mMinimumDisplayTime = resources.getInteger(R.integer.ambient_notification_minimum_time);
+        mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
+    }
+
+    /**
+     * Adds an OnAmbientChangedListener to observe events.
+     */
+    public void addListener(@NonNull OnAmbientChangedListener listener) {
+        mListeners.add(listener);
+    }
+
+    /**
+     * Removes the OnAmbientChangedListener from the observer list.
+     */
+    public void removeListener(@NonNull OnAmbientChangedListener listener) {
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
+     * longer.
+     */
+    public void extendPulse() {
+        AmbientEntry topEntry = getTopEntry();
+        if (topEntry == null) {
+            return;
+        }
+        topEntry.extendPulse();
+    }
+
+    @Override
+    protected void onAlertEntryAdded(AlertEntry alertEntry) {
+        NotificationData.Entry entry = alertEntry.mEntry;
+        entry.row.setAmbientPulsing(true);
+        for (OnAmbientChangedListener listener : mListeners) {
+            listener.onAmbientStateChanged(entry, true);
+        }
+    }
+
+    @Override
+    protected void onAlertEntryRemoved(AlertEntry alertEntry) {
+        NotificationData.Entry entry = alertEntry.mEntry;
+        entry.row.setAmbientPulsing(false);
+        for (OnAmbientChangedListener listener : mListeners) {
+            listener.onAmbientStateChanged(entry, false);
+        }
+    }
+
+    @Override
+    protected AlertEntry createAlertEntry() {
+        return new AmbientEntry();
+    }
+
+    /**
+     * Get the top pulsing entry.  This should be the currently showing one if there are multiple.
+     * @return the currently showing entry
+     */
+    private AmbientEntry getTopEntry() {
+        if (mAlertEntries.isEmpty()) {
+            return null;
+        }
+        AlertEntry topEntry = null;
+        for (AlertEntry entry : mAlertEntries.values()) {
+            if (topEntry == null || entry.compareTo(topEntry) < 0) {
+                topEntry = entry;
+            }
+        }
+        return (AmbientEntry) topEntry;
+    }
+
+    /**
+     * Observer interface for any changes in the ambient entries.
+     */
+    public interface OnAmbientChangedListener {
+        /**
+         * Called when an entry starts or stops pulsing.
+         * @param entry the entry that changed
+         * @param isPulsing true if the entry is now pulsing, false otherwise
+         */
+        void onAmbientStateChanged(NotificationData.Entry entry, boolean isPulsing);
+    }
+
+    private final class AmbientEntry extends AlertEntry {
+        private boolean extended;
+
+        /**
+         * Extend the lifetime of the alertEntry so that it auto-removes later.  Can only be
+         * extended once.
+         */
+        private void extendPulse() {
+            if (!extended) {
+                extended = true;
+                updateEntry(false);
+            }
+        }
+
+        @Override
+        public void reset() {
+            super.reset();
+            extended = false;
+        }
+
+        @Override
+        protected long calculateFinishTime() {
+            return super.calculateFinishTime() + (extended ? mExtensionTime : 0);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index e19c844..5c0b328 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -161,7 +161,7 @@
         default void onRotationProposal(int rotation, boolean isValid) { }
 
         default void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver,
-                int type) { }
+                int type, boolean requireConfirmation) { }
         default void onBiometricAuthenticated() { }
         default void onBiometricHelp(String message) { }
         default void onBiometricError(String error) { }
@@ -514,12 +514,14 @@
     }
 
     @Override
-    public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type) {
+    public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type,
+            boolean requireConfirmation) {
         synchronized (mLock) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = bundle;
             args.arg2 = receiver;
             args.argi1 = type;
+            args.arg3 = requireConfirmation;
             mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
                     .sendToTarget();
         }
@@ -763,7 +765,8 @@
                         mCallbacks.get(i).showBiometricDialog(
                                 (Bundle) someArgs.arg1,
                                 (IBiometricPromptReceiver) someArgs.arg2,
-                                someArgs.argi1);
+                                someArgs.argi1,
+                                (boolean) someArgs.arg3);
                     }
                     someArgs.recycle();
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 247e3d3..00e0b95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.statusbar;
 
+import static android.content.Context.LAYOUT_INFLATER_SERVICE;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AlertDialog;
@@ -30,10 +34,10 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.ResolveInfo;
 import android.content.res.ColorStateList;
-import android.graphics.drawable.Icon;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.Looper;
@@ -51,29 +55,23 @@
 import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowManager;
 import android.view.WindowManager.KeyboardShortcutsReceiver;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
-
 import com.android.internal.app.AssistUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-import static android.content.Context.LAYOUT_INFLATER_SERVICE;
-import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-
 /**
  * Contains functionality for handling keyboard shortcuts.
  */
@@ -372,19 +370,19 @@
 
     private void showKeyboardShortcuts(int deviceId) {
         retrieveKeyCharacterMap(deviceId);
-        SystemServicesProxy.getInstance(mContext).requestKeyboardShortcuts(mContext,
-                new KeyboardShortcutsReceiver() {
-                    @Override
-                    public void onKeyboardShortcutsReceived(
-                            final List<KeyboardShortcutGroup> result) {
-                        result.add(getSystemShortcuts());
-                        final KeyboardShortcutGroup appShortcuts = getDefaultApplicationShortcuts();
-                        if (appShortcuts != null) {
-                            result.add(appShortcuts);
-                        }
-                        showKeyboardShortcutsDialog(result);
-                    }
-                }, deviceId);
+        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        wm.requestAppKeyboardShortcuts(new KeyboardShortcutsReceiver() {
+            @Override
+            public void onKeyboardShortcutsReceived(
+                    final List<KeyboardShortcutGroup> result) {
+                result.add(getSystemShortcuts());
+                final KeyboardShortcutGroup appShortcuts = getDefaultApplicationShortcuts();
+                if (appShortcuts != null) {
+                    result.add(appShortcuts);
+                }
+                showKeyboardShortcutsDialog(result);
+            }
+        }, deviceId);
     }
 
     private void dismissKeyboardShortcuts() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index e12b574..9d773ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -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;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 551e8a9..0c5f391 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -298,27 +298,6 @@
         if (mVisible) {
             // Walk down a precedence-ordered list of what indication
             // should be shown based on user or device state
-            if (mDozing) {
-                mTextView.setTextColor(Color.WHITE);
-                if (!TextUtils.isEmpty(mTransientIndication)) {
-                    // When dozing we ignore any text color and use white instead, because
-                    // colors can be hard to read in low brightness.
-                    mTextView.switchIndication(mTransientIndication);
-                } else if (mPowerPluggedIn) {
-                    String indication = computePowerIndication();
-                    if (animate) {
-                        animateText(mTextView, indication);
-                    } else {
-                        mTextView.switchIndication(indication);
-                    }
-                } else {
-                    String percentage = NumberFormat.getPercentInstance()
-                            .format(mBatteryLevel / 100f);
-                    mTextView.switchIndication(percentage);
-                }
-                return;
-            }
-
             KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
             int userId = KeyguardUpdateMonitor.getCurrentUser();
             String trustGrantedIndication = getTrustGrantedIndication();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
index d6886f5..89a842e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
@@ -16,6 +16,7 @@
 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;
@@ -37,12 +38,15 @@
 
 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 java.io.FileDescriptor;
@@ -52,7 +56,7 @@
  * 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 {
+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";
@@ -67,9 +71,13 @@
             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
@@ -84,7 +92,9 @@
                 mEntryManager.updateNotifications();
             } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) {
                 if (userId != mCurrentUserId && isCurrentProfile(userId)) {
+                    updatePublicMode();
                     mPresenter.onWorkChallengeChanged();
+                    mEntryManager.updateNotifications();
                 }
             }
         }
@@ -100,8 +110,9 @@
                 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)) {
@@ -150,6 +161,9 @@
         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,
@@ -239,6 +253,43 @@
         }
     }
 
+    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);
+        }
+    }
+
     /**
      * Returns true if notifications are temporarily disabled for this user for security reasons,
      * regardless of the normal settings for that user.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index f7615e6..d8f7b61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -121,7 +121,8 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class)
+                .addListener(mStateListener, StatusBarStateController.RANK_SHELF);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index d479838..f69ad43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -321,7 +321,7 @@
                         && !row.isLowPriority()));
             }
 
-            entry.row.setShowAmbient(mPresenter.isDozing());
+            entry.row.setOnAmbient(mPresenter.isDozing());
             int userId = entry.notification.getUserId();
             boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
                     entry.notification) && !entry.row.isRemoved();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
index 7a69f2e..d6719f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
@@ -16,42 +16,70 @@
 
 package com.android.systemui.statusbar;
 
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
 import android.util.ArraySet;
+import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Comparator;
 
 /**
  * Tracks and reports on {@link StatusBarState}.
  */
 public class StatusBarStateController {
+    private static final String TAG = "SbStateController";
 
     private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER;
     private static final int MIN_STATE = StatusBarState.SHADE;
 
-    private final ArraySet<StateListener> mListeners = new ArraySet<>();
+    private static final Comparator <RankedListener> mComparator
+            = (o1, o2) -> Integer.compare(o1.rank, o2.rank);
+
+    private final ArrayList<RankedListener> mListeners = new ArrayList<>();
     private int mState;
     private int mLastState;
     private boolean mLeaveOpenOnKeyguardHide;
 
+    // TODO: b/115739177 (remove this explicit ordering if we can)
+    @Retention(SOURCE)
+    @IntDef({RANK_STATUS_BAR, RANK_STATUS_BAR_WINDOW_CONTROLLER, RANK_STACK_SCROLLER, RANK_SHELF})
+    public @interface SbStateListenerRank {}
+    // This is the set of known dependencies when updating StatusBarState
+    public static final int RANK_STATUS_BAR = 0;
+    public static final int RANK_STATUS_BAR_WINDOW_CONTROLLER = 1;
+    public static final int RANK_STACK_SCROLLER = 2;
+    public static final int RANK_SHELF = 3;
+
     public int getState() {
         return mState;
     }
 
-    public void setState(int state) {
+    public boolean setState(int state) {
         if (state > MAX_STATE || state < MIN_STATE) {
             throw new IllegalArgumentException("Invalid state " + state);
         }
         if (state == mState) {
-            return;
+            return false;
         }
         synchronized (mListeners) {
-            for (StateListener listener : new ArraySet<>(mListeners)) {
-                listener.onStatePreChange(mState, state);
+            for (RankedListener rl : new ArrayList<>(mListeners)) {
+                rl.listener.onStatePreChange(mState, state);
             }
             mLastState = mState;
             mState = state;
-            for (StateListener listener : new ArraySet<>(mListeners)) {
-                listener.onStateChanged(mState);
+            for (RankedListener rl : new ArrayList<>(mListeners)) {
+                rl.listener.onStateChanged(mState);
+            }
+
+            for (RankedListener rl : new ArrayList<>(mListeners)) {
+                rl.listener.onStatePostChange();
             }
         }
+
+        return true;
     }
 
     public boolean goingToFullShade() {
@@ -72,20 +100,67 @@
 
     public void addListener(StateListener listener) {
         synchronized (mListeners) {
-            mListeners.add(listener);
+            addListenerInternalLocked(listener, Integer.MAX_VALUE);
         }
     }
 
+    /**
+     * Add a listener and a rank based on the priority of this message
+     * @param listener the listener
+     * @param rank the order in which you'd like to be called. Ranked listeners will be
+     * notified before unranked, and we will sort ranked listeners from low to high
+     *
+     * @deprecated This method exists only to solve latent inter-dependencies from refactoring
+     * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
+     * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
+     */
+    public void addListener(StateListener listener, @SbStateListenerRank int rank) {
+        synchronized (mListeners) {
+            addListenerInternalLocked(listener, rank);
+        }
+    }
+
+    @GuardedBy("mListeners")
+    private void addListenerInternalLocked(StateListener listener, int rank) {
+        // Protect against double-subscribe
+        for (RankedListener rl : mListeners) {
+            if (rl.listener.equals(listener)) {
+                return;
+            }
+        }
+
+        RankedListener rl = new RankedListener(listener, rank);
+        mListeners.add(rl);
+        mListeners.sort(mComparator);
+    }
+
     public void removeListener(StateListener listener) {
         synchronized (mListeners) {
-            mListeners.remove(listener);
+            mListeners.removeIf((it) -> it.listener.equals(listener));
         }
     }
 
+    public static String describe(int state) {
+        return StatusBarState.toShortString(state);
+    }
+
     public interface StateListener {
         public default void onStatePreChange(int oldState, int newState) {
         }
 
+        public default void onStatePostChange() {
+        }
+
         public void onStateChanged(int newState);
     }
+
+    private class RankedListener {
+        private final StateListener listener;
+        private final int rank;
+
+        private RankedListener(StateListener l, int r) {
+            listener = l;
+            rank = r;
+        }
+    }
 }
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 304a00f..2450e44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.car;
 
 import android.app.ActivityTaskManager;
-import android.car.user.CarUserManagerHelper;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 import android.util.Log;
@@ -36,8 +35,8 @@
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.car.hvac.HvacController;
 import com.android.systemui.statusbar.car.hvac.TemperatureView;
@@ -461,16 +460,11 @@
         }
     }
 
-
-    public boolean hasDockedTask() {
-        return Recents.getSystemServices().hasDockedTask();
-    }
-
     /**
-     * An implementation of SysUiTaskStackChangeListener, that listens for changes in the system
+     * An implementation of TaskStackChangeListener, that listens for changes in the system
      * task stack and notifies the navigation bar.
      */
-    private class TaskStackListenerImpl extends SysUiTaskStackChangeListener {
+    private class TaskStackListenerImpl extends TaskStackChangeListener {
         @Override
         public void onTaskStackChanged() {
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 67e512c..618a4c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -22,7 +22,7 @@
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
 import android.app.Dialog;
-import android.car.user.CarUserManagerHelper;
+import android.car.userlib.CarUserManagerHelper;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.UserInfo;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 53d38c4..f0e5462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -29,18 +29,14 @@
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationTarget;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.shared.system.SurfaceControlCompat;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
-import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 
 /**
@@ -59,28 +55,28 @@
     private final NotificationPanelView mNotificationPanel;
     private final NotificationListContainer mNotificationContainer;
     private final StatusBarWindowView mStatusBarWindow;
-    private final StatusBarStateController mStatusBarStateController;
-    private StatusBar mStatusBar;
+    private Callback mCallback;
     private final Runnable mTimeoutRunnable = () -> {
         setAnimationPending(false);
-        mStatusBar.collapsePanel(true /* animate */);
+        mCallback.onExpandAnimationTimedOut();
     };
     private boolean mAnimationPending;
+    private boolean mAnimationRunning;
+    private boolean mIsLaunchForActivity;
 
     public ActivityLaunchAnimator(StatusBarWindowView statusBarWindow,
-            StatusBar statusBar,
+            Callback callback,
             NotificationPanelView notificationPanel,
             NotificationListContainer container) {
         mNotificationPanel = notificationPanel;
         mNotificationContainer = container;
         mStatusBarWindow = statusBarWindow;
-        mStatusBar = statusBar;
-        mStatusBarStateController = Dependency.get(StatusBarStateController.class);
+        mCallback = callback;
     }
 
     public RemoteAnimationAdapter getLaunchAnimation(
             ExpandableNotificationRow sourceNotification, boolean occluded) {
-        if (mStatusBarStateController.getState() != StatusBarState.SHADE || occluded) {
+        if (!mCallback.areLaunchAnimationsEnabled() || occluded) {
             return null;
         }
         AnimationRunner animationRunner = new AnimationRunner(sourceNotification);
@@ -92,10 +88,21 @@
         return mAnimationPending;
     }
 
-    public void setLaunchResult(int launchResult) {
+    /**
+     * Set the launch result the intent requested
+     *
+     * @param launchResult the launch result
+     * @param wasIntentActivity was this launch for an activity
+     */
+    public void setLaunchResult(int launchResult, boolean wasIntentActivity) {
+        mIsLaunchForActivity = wasIntentActivity;
         setAnimationPending((launchResult == ActivityManager.START_TASK_TO_FRONT
                 || launchResult == ActivityManager.START_SUCCESS)
-                        && mStatusBarStateController.getState() == StatusBarState.SHADE);
+                        && mCallback.areLaunchAnimationsEnabled());
+    }
+
+    public boolean isLaunchForActivity() {
+        return mIsLaunchForActivity;
     }
 
     private void setAnimationPending(boolean pending) {
@@ -108,12 +115,16 @@
         }
     }
 
+    public boolean isAnimationRunning() {
+        return mAnimationRunning;
+    }
+
     class AnimationRunner extends IRemoteAnimationRunner.Stub {
 
         private final ExpandableNotificationRow mSourceNotification;
         private final ExpandAnimationParameters mParams;
         private final Rect mWindowCrop = new Rect();
-        private boolean mInstantCollapsePanel = true;
+        private boolean mIsFullScreenLaunch = true;
         private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier;
 
         public AnimationRunner(ExpandableNotificationRow sourceNofitication) {
@@ -136,10 +147,10 @@
                 }
 
                 setExpandAnimationRunning(true);
-                mInstantCollapsePanel = primary.position.y == 0
+                mIsFullScreenLaunch = primary.position.y == 0
                         && primary.sourceContainerBounds.height()
                                 >= mNotificationPanel.getHeight();
-                if (!mInstantCollapsePanel) {
+                if (!mIsFullScreenLaunch) {
                     mNotificationPanel.collapseWithDuration(ANIMATION_DURATION);
                 }
                 ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
@@ -192,9 +203,6 @@
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         setExpandAnimationRunning(false);
-                        if (mInstantCollapsePanel) {
-                            mStatusBar.collapsePanel(false /* animate */);
-                        }
                         invokeCallback(iRemoteAnimationFinishedCallback);
                     }
                 });
@@ -228,7 +236,9 @@
             mSourceNotification.setExpandAnimationRunning(running);
             mStatusBarWindow.setExpandAnimationRunning(running);
             mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null);
+            mAnimationRunning = running;
             if (!running) {
+                mCallback.onExpandAnimationFinished(mIsFullScreenLaunch);
                 applyParamsToNotification(null);
                 applyParamsToNotificationList(null);
             }
@@ -257,7 +267,7 @@
         public void onAnimationCancelled() throws RemoteException {
             mSourceNotification.post(() -> {
                 setAnimationPending(false);
-                mStatusBar.onLaunchAnimationCancelled();
+                mCallback.onLaunchAnimationCancelled();
             });
         }
     };
@@ -319,4 +329,30 @@
             return startTranslationZ;
         }
     }
+
+    public interface Callback {
+
+        /**
+         * Called when the launch animation was cancelled.
+         */
+        void onLaunchAnimationCancelled();
+
+        /**
+         * Called when the launch animation has timed out without starting an actual animation.
+         */
+        void onExpandAnimationTimedOut();
+
+        /**
+         * Called when the expand animation has finished.
+         *
+         * @param launchIsFullScreen True if this launch was fullscreen, such that now the window
+         *                           fills the whole screen
+         */
+        void onExpandAnimationFinished(boolean launchIsFullScreen);
+
+        /**
+         * Are animations currently enabled.
+         */
+        boolean areLaunchAnimationsEnabled();
+    }
 }
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 804e842..d097c8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
@@ -440,6 +440,8 @@
             } else if (isHeadsUp) {
                 // Provide consistent ranking with headsUpManager
                 return mHeadsUpManager.compare(a, b);
+            } else if (a.row.isAmbientPulsing() != b.row.isAmbientPulsing()) {
+                return a.row.isAmbientPulsing() ? -1 : 1;
             } else if (aMedia != bMedia) {
                 // Upsort current media notification.
                 return aMedia ? -1 : 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index ac01fa3..a3e982e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -28,15 +28,19 @@
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
@@ -56,8 +60,9 @@
 import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
+import com.android.systemui.statusbar.AlertingNotificationManager;
+import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationMediaManager;
@@ -91,7 +96,7 @@
         ExpandableNotificationRow.ExpansionLogger, NotificationUpdateHandler,
         VisualStabilityManager.Callback {
     private static final String TAG = "NotificationEntryMgr";
-    protected static final boolean DEBUG = false;
+    protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     protected static final boolean ENABLE_HEADS_UP = true;
     protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
 
@@ -121,12 +126,13 @@
             Dependency.get(ForegroundServiceController.class);
     protected final NotificationListener mNotificationListener =
             Dependency.get(NotificationListener.class);
+    protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
 
+    protected IDreamManager mDreamManager;
     protected IStatusBarService mBarService;
     protected NotificationPresenter mPresenter;
     protected Callback mCallback;
     protected PowerManager mPowerManager;
-    protected SystemServicesProxy mSystemServicesProxy;
     protected NotificationListenerService.RankingMap mLatestRankingMap;
     protected HeadsUpManager mHeadsUpManager;
     protected NotificationData mNotificationData;
@@ -218,8 +224,9 @@
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mMessagingUtil = new NotificationMessagingUtil(context);
-        mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
         mGroupManager.setPendingEntries(mPendingNotifications);
     }
 
@@ -264,6 +271,7 @@
         }
 
         mNotificationLifetimeExtenders.add(mHeadsUpManager);
+        mNotificationLifetimeExtenders.add(mAmbientPulseManager);
         mNotificationLifetimeExtenders.add(mGutsManager);
         mNotificationLifetimeExtenders.addAll(mRemoteInputManager.getLifetimeExtenders());
 
@@ -381,7 +389,7 @@
         final int userId = n.getUserId();
         try {
             int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
-            if (isHeadsUp(n.getKey())) {
+            if (mHeadsUpManager.isAlerting(n.getKey())) {
                 dismissalSurface = NotificationStats.DISMISSAL_PEEK;
             } else if (mListContainer.hasPulsingNotifications()) {
                 dismissalSurface = NotificationStats.DISMISSAL_AOD;
@@ -432,12 +440,14 @@
     }
 
     private void addEntry(NotificationData.Entry shadeEntry) {
-        boolean isHeadsUped = shouldPeek(shadeEntry);
-        if (isHeadsUped) {
+        if (shouldHeadsUp(shadeEntry)) {
             mHeadsUpManager.showNotification(shadeEntry);
             // Mark as seen immediately
             setNotificationShown(shadeEntry.notification);
         }
+        if (shouldPulse(shadeEntry)) {
+            mAmbientPulseManager.showNotification(shadeEntry);
+        }
         addNotificationViews(shadeEntry);
         mCallback.onNotificationAdded(shadeEntry);
     }
@@ -465,7 +475,11 @@
     private void removeNotificationInternal(String key,
             @Nullable NotificationListenerService.RankingMap ranking, boolean forceRemove) {
         abortExistingInflation(key);
-        if (mHeadsUpManager.contains(key)) {
+
+        // Attempt to remove notifications from their alert managers (heads up, ambient pulse).
+        // Though the remove itself may fail, it lets the manager know to remove as soon as
+        // possible.
+        if (mHeadsUpManager.isAlerting(key)) {
             // A cancel() in response to a remote input shouldn't be delayed, as it makes the
             // sending look longer than it takes.
             // Also we should not defer the removal if reordering isn't allowed since otherwise
@@ -473,10 +487,11 @@
             boolean ignoreEarliestRemovalTime = mRemoteInputManager.getController().isSpinning(key)
                     && !FORCE_REMOTE_INPUT_HISTORY
                     || !mVisualStabilityManager.isReorderingAllowed();
-
-            // Attempt to remove notification.
             mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
         }
+        if (mAmbientPulseManager.isAlerting(key)) {
+            mAmbientPulseManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
+        }
 
         NotificationData.Entry entry = mNotificationData.get(key);
 
@@ -651,13 +666,15 @@
     private void addNotificationInternal(StatusBarNotification notification,
             NotificationListenerService.RankingMap rankingMap) throws InflationException {
         String key = notification.getKey();
-        if (DEBUG) Log.d(TAG, "addNotification key=" + key);
+        if (DEBUG) {
+            Log.d(TAG, "addNotification key=" + key);
+        }
 
         mNotificationData.updateRanking(rankingMap);
         NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking();
         rankingMap.getRanking(key, ranking);
         NotificationData.Entry shadeEntry = createNotificationViews(notification, ranking);
-        boolean isHeadsUped = shouldPeek(shadeEntry);
+        boolean isHeadsUped = shouldHeadsUp(shadeEntry);
         if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
             if (shouldSuppressFullScreenIntent(shadeEntry)) {
                 if (DEBUG) {
@@ -672,7 +689,13 @@
             } else {
                 // Stop screensaver if the notification has a fullscreen intent.
                 // (like an incoming phone call)
-                SystemServicesProxy.getInstance(mContext).awakenDreamsAsync();
+                Dependency.get(UiOffloadThread.class).submit(() -> {
+                    try {
+                        mDreamManager.awaken();
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                    }
+                });
 
                 // not immersive & a fullscreen alert should be shown
                 if (DEBUG)
@@ -750,7 +773,6 @@
             extender.setShouldManageLifetime(entry, false /* shouldManage */);
         }
 
-        Notification n = notification.getNotification();
         mNotificationData.updateRanking(ranking);
 
         final StatusBarNotification oldNotification = entry.notification;
@@ -763,10 +785,12 @@
         mForegroundServiceController.updateNotification(notification,
                 mNotificationData.getImportance(key));
 
-        boolean shouldPeek = shouldPeek(entry, notification);
-        boolean alertAgain = alertAgain(entry, n);
-
-        updateHeadsUp(key, entry, shouldPeek, alertAgain);
+        boolean alertAgain = alertAgain(entry, entry.notification.getNotification());
+        if (mPresenter.isDozing()) {
+            updateAlertState(entry, shouldPulse(entry), alertAgain, mAmbientPulseManager);
+        } else {
+            updateAlertState(entry, shouldHeadsUp(entry), alertAgain, mHeadsUpManager);
+        }
         updateNotifications();
 
         if (!notification.isClearable()) {
@@ -851,66 +875,163 @@
         }
     }
 
-    protected boolean shouldPeek(NotificationData.Entry entry) {
-        return shouldPeek(entry, entry.notification);
-    }
+    /**
+     * Whether the notification should peek in from the top and alert the user.
+     *
+     * @param entry the entry to check
+     * @return true if the entry should heads up, false otherwise
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
+    public boolean shouldHeadsUp(NotificationData.Entry entry) {
+        StatusBarNotification sbn = entry.notification;
 
-    public boolean shouldPeek(NotificationData.Entry entry, StatusBarNotification sbn) {
-        if (!mUseHeadsUp || mPresenter.isDeviceInVrMode()) {
-            if (DEBUG) Log.d(TAG, "No peeking: no huns or vr mode");
-            return false;
-        }
-
-        if (mNotificationData.shouldFilterOut(entry)) {
-            if (DEBUG) Log.d(TAG, "No peeking: filtered notification: " + sbn.getKey());
-            return false;
-        }
-
-        boolean inUse = mPowerManager.isScreenOn() && !mSystemServicesProxy.isDreaming();
-
-        if (!inUse && !mPresenter.isDozing()) {
+        if (mPresenter.isDozing()) {
             if (DEBUG) {
-                Log.d(TAG, "No peeking: not in use: " + sbn.getKey());
+                Log.d(TAG, "No heads up: device is dozing: " + sbn.getKey());
             }
             return false;
         }
 
-        if (!mPresenter.isDozing() && mNotificationData.shouldSuppressPeek(entry)) {
-            if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
+        if (!canAlertCommon(entry)) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: notification shouldn't alert: " + sbn.getKey());
+            }
             return false;
         }
 
-        // Peeking triggers an ambient display pulse, so disable peek is ambient is active
-        if (mPresenter.isDozing() && mNotificationData.shouldSuppressAmbient(entry)) {
-            if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
+        if (!mUseHeadsUp || mPresenter.isDeviceInVrMode()) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: no huns or vr mode");
+            }
             return false;
         }
 
-        if (entry.hasJustLaunchedFullScreenIntent()) {
-            if (DEBUG) Log.d(TAG, "No peeking: recent fullscreen: " + sbn.getKey());
+        boolean isDreaming = false;
+        try {
+            isDreaming = mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to query dream manager.", e);
+        }
+        boolean inUse = mPowerManager.isScreenOn() && !isDreaming;
+
+        if (!inUse) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: not in use: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (mNotificationData.shouldSuppressPeek(entry)) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: suppressed by DND: " + sbn.getKey());
+            }
             return false;
         }
 
         if (isSnoozedPackage(sbn)) {
-            if (DEBUG) Log.d(TAG, "No peeking: snoozed package: " + sbn.getKey());
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: snoozed package: " + sbn.getKey());
+            }
             return false;
         }
 
-        // Allow peeking for DEFAULT notifications only if we're on Ambient Display.
-        int importanceLevel = mPresenter.isDozing() ? NotificationManager.IMPORTANCE_DEFAULT
-                : NotificationManager.IMPORTANCE_HIGH;
-        if (mNotificationData.getImportance(sbn.getKey()) < importanceLevel) {
-            if (DEBUG) Log.d(TAG, "No peeking: unimportant notification: " + sbn.getKey());
+        if (entry.hasJustLaunchedFullScreenIntent()) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: recent fullscreen: " + sbn.getKey());
+            }
             return false;
         }
 
-        // Don't peek notifications that are suppressed due to group alert behavior
+        if (mNotificationData.getImportance(sbn.getKey()) < NotificationManager.IMPORTANCE_HIGH) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: unimportant notification: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (!mCallback.canHeadsUp(entry, sbn)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Whether or not the notification should "pulse" on the user's display when the phone is
+     * dozing.  This displays the ambient view of the notification.
+     *
+     * @param entry the entry to check
+     * @return true if the entry should ambient pulse, false otherwise
+     */
+    protected boolean shouldPulse(NotificationData.Entry entry) {
+        StatusBarNotification sbn = entry.notification;
+
+        if (!mPresenter.isDozing()) {
+            if (DEBUG) {
+                Log.d(TAG, "No pulsing: not dozing: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (!canAlertCommon(entry)) {
+            if (DEBUG) {
+                Log.d(TAG, "No pulsing: notification shouldn't alert: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (mNotificationData.shouldSuppressAmbient(entry)) {
+            if (DEBUG) {
+                Log.d(TAG, "No pulsing: ambient effect suppressed: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (mNotificationData.getImportance(sbn.getKey())
+                < NotificationManager.IMPORTANCE_DEFAULT) {
+            if (DEBUG) {
+                Log.d(TAG, "No pulsing: not important enough: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        Bundle extras = sbn.getNotification().extras;
+        CharSequence title = extras.getCharSequence(Notification.EXTRA_TITLE);
+        CharSequence text = extras.getCharSequence(Notification.EXTRA_TEXT);
+        if (TextUtils.isEmpty(title) && TextUtils.isEmpty(text)) {
+            if (DEBUG) {
+                Log.d(TAG, "No pulsing: title and text are empty: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Common checks between heads up alerting and ambient pulse alerting.  See
+     * {@link NotificationEntryManager#shouldHeadsUp(NotificationData.Entry)} and
+     * {@link NotificationEntryManager#shouldPulse(NotificationData.Entry)}.  Notifications that
+     * fail any of these checks should not alert at all.
+     *
+     * @param entry the entry to check
+     * @return true if these checks pass, false if the notification should not alert
+     */
+    protected boolean canAlertCommon(NotificationData.Entry entry) {
+        StatusBarNotification sbn = entry.notification;
+
+        if (mNotificationData.shouldFilterOut(entry)) {
+            if (DEBUG) {
+                Log.d(TAG, "No alerting: filtered notification: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        // Don't alert notifications that are suppressed due to group alert behavior
         if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
-            if (DEBUG) Log.d(TAG, "No peeking: suppressed due to group alert behavior");
-            return false;
-        }
-
-        if (!mCallback.shouldPeek(entry, sbn)) {
+            if (DEBUG) {
+                Log.d(TAG, "No alerting: suppressed due to group alert behavior");
+            }
             return false;
         }
 
@@ -933,26 +1054,31 @@
         return mHeadsUpManager.isSnoozed(sbn.getPackageName());
     }
 
-    protected void updateHeadsUp(String key, NotificationData.Entry entry, boolean shouldPeek,
-            boolean alertAgain) {
-        final boolean wasHeadsUp = isHeadsUp(key);
-        if (wasHeadsUp) {
-            if (!shouldPeek) {
+    /**
+     * Update the entry's alert state and call the appropriate {@link AlertingNotificationManager}
+     * method.
+     * @param entry entry to update
+     * @param shouldAlert whether or not it should be alerting
+     * @param alertAgain whether or not an alert should actually come in as if it were new
+     * @param alertManager the alerting notification manager that manages the alert state
+     */
+    private void updateAlertState(NotificationData.Entry entry, boolean shouldAlert,
+            boolean alertAgain, AlertingNotificationManager alertManager) {
+        final boolean wasAlerting = alertManager.isAlerting(entry.key);
+        if (wasAlerting) {
+            if (!shouldAlert) {
                 // We don't want this to be interrupting anymore, lets remove it
-                mHeadsUpManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
+                alertManager.removeNotification(entry.key,
+                        false /* ignoreEarliestRemovalTime */);
             } else {
-                mHeadsUpManager.updateNotification(entry.key, alertAgain);
+                alertManager.updateNotification(entry.key, alertAgain);
             }
-        } else if (shouldPeek && alertAgain) {
-            // This notification was updated to be a heads-up, show it!
-            mHeadsUpManager.showNotification(entry);
+        } else if (shouldAlert && alertAgain) {
+            // This notification was updated to be alerting, show it!
+            alertManager.showNotification(entry);
         }
     }
 
-    protected boolean isHeadsUp(String key) {
-        return mHeadsUpManager.contains(key);
-    }
-
     /**
      * Callback for NotificationEntryManager.
      */
@@ -1008,12 +1134,12 @@
         void onPerformRemoveNotification(StatusBarNotification statusBarNotification);
 
         /**
-         * Returns true if NotificationEntryManager should peek this notification.
+         * Returns true if NotificationEntryManager can heads up this notification.
          *
-         * @param entry entry of the notification that might be peeked
-         * @param sbn notification that might be peeked
-         * @return true if the notification should be peeked
+         * @param entry entry of the notification that might be heads upped
+         * @param sbn notification that might be heads upped
+         * @return true if the notification can be heads upped
          */
-        boolean shouldPeek(NotificationData.Entry entry, StatusBarNotification sbn);
+        boolean canHeadsUp(NotificationData.Entry entry, StatusBarNotification sbn);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ShadeViewRefactor.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ShadeViewRefactor.java
index f204c42..5ad2ba9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ShadeViewRefactor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ShadeViewRefactor.java
@@ -14,7 +14,10 @@
  * limitations under the License
  */
 
-package java.lang.annotation;
+package com.android.systemui.statusbar.notification;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 @Retention(RetentionPolicy.SOURCE)
 public @interface ShadeViewRefactor {
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 216ed68..bce613a 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
@@ -72,7 +72,7 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+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;
@@ -174,6 +174,11 @@
      */
     private boolean mOnKeyguard;
 
+    /**
+     * Whether or not the row is currently on the doze screen.
+     */
+    private boolean mOnAmbient;
+
     private Animator mTranslateAnim;
     private ArrayList<View> mTranslateableViews;
     private NotificationContentView mPublicLayout;
@@ -186,7 +191,18 @@
     private NotificationData.Entry mEntry;
     private StatusBarNotification mStatusBarNotification;
     private String mAppName;
+
+    /**
+     * Whether or not the notification is using the heads up view and should peek from the top.
+     */
     private boolean mIsHeadsUp;
+
+    /**
+     * Whether or not the notification is using the ambient display view and is pulsing.  This
+     * occurs when a high priority notification alerts while the phone is dozing or is on AOD.
+     */
+    private boolean mIsAmbientPulsing;
+
     private boolean mLastChronometerRunning = true;
     private ViewStub mChildrenContainerStub;
     private NotificationGroupManager mGroupManager;
@@ -289,7 +305,6 @@
     private float mContentTransformationAmount;
     private boolean mIconsVisible = true;
     private boolean mAboveShelf;
-    private boolean mShowAmbient;
     private boolean mIsLastChild;
     private Runnable mOnDismissRunnable;
     private boolean mIsLowPriority;
@@ -606,6 +621,14 @@
         }
     }
 
+    public boolean isAmbientPulsing() {
+        return mIsAmbientPulsing;
+    }
+
+    public void setAmbientPulsing(boolean isAmbientPulsing) {
+        mIsAmbientPulsing = isAmbientPulsing;
+    }
+
     public void setGroupManager(NotificationGroupManager groupManager) {
         mGroupManager = groupManager;
         mPrivateLayout.setGroupManager(groupManager);
@@ -1014,7 +1037,7 @@
             removeView(mMenuRow.getMenuView());
         }
         mMenuRow = plugin;
-        if (mMenuRow.useDefaultMenuItems()) {
+        if (mMenuRow.shouldUseDefaultMenuItems()) {
             ArrayList<MenuItem> items = new ArrayList<>();
             items.add(NotificationMenuRow.createInfoItem(mContext));
             items.add(NotificationMenuRow.createSnoozeItem(mContext));
@@ -1764,7 +1787,7 @@
             getEntry().expandedIcon.setScrollX((int) -translationX);
         }
         if (mMenuRow.getMenuView() != null) {
-            mMenuRow.onTranslationUpdate(translationX);
+            mMenuRow.onParentTranslationUpdate(translationX);
         }
     }
 
@@ -1854,7 +1877,7 @@
     public void setDark(boolean dark, boolean fade, long delay) {
         super.setDark(dark, fade, delay);
         mDark = dark;
-        if (!mIsHeadsUp) {
+        if (!mIsAmbientPulsing) {
             // Only fade the showing view of the pulsing notification.
             fade = false;
         }
@@ -2155,7 +2178,7 @@
             return mPrivateLayout.getMinHeight();
         } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
             return getMinHeight();
-        } else if (mIsSummaryWithChildren && (!mOnKeyguard || mShowAmbient)) {
+        } else if (mIsSummaryWithChildren && (!mOnKeyguard || mOnAmbient)) {
             return mChildrenContainer.getIntrinsicHeight();
         } else if (isHeadsUpAllowed() && (mIsHeadsUp || mHeadsupDisappearRunning)) {
             if (isPinned() || mHeadsupDisappearRunning) {
@@ -2173,7 +2196,7 @@
     }
 
     private boolean isHeadsUpAllowed() {
-        return !mOnKeyguard && !mShowAmbient;
+        return !mOnKeyguard && !mOnAmbient;
     }
 
     @Override
@@ -2269,7 +2292,7 @@
             notifyHeightChanged(true  /* needsAnimation */);
         }
         if (mMenuRow.getMenuView() != null) {
-            mMenuRow.onHeightUpdate();
+            mMenuRow.onParentHeightUpdate();
         }
         updateContentShiftHeight();
         if (mLayoutListener != null) {
@@ -2520,7 +2543,7 @@
             mGuts.setActualHeight(height);
         }
         if (mMenuRow.getMenuView() != null) {
-            mMenuRow.onHeightUpdate();
+            mMenuRow.onParentHeightUpdate();
         }
     }
 
@@ -2818,11 +2841,11 @@
                 || mExpandAnimationRunning || mChildIsExpanding);
     }
 
-    public void setShowAmbient(boolean showAmbient) {
-        if (showAmbient != mShowAmbient) {
-            mShowAmbient = showAmbient;
+    public void setOnAmbient(boolean onAmbient) {
+        if (onAmbient != mOnAmbient) {
+            mOnAmbient = onAmbient;
             if (mChildrenContainer != null) {
-                mChildrenContainer.notifyShowAmbientChanged();
+                mChildrenContainer.notifyDozingStateChanged();
             }
             notifyHeightChanged(false /* needsAnimation */);
         }
@@ -2891,8 +2914,8 @@
         return getCurrentBottomRoundness() == 0.0f && getCurrentTopRoundness() == 0.0f;
     }
 
-    public boolean isShowingAmbient() {
-        return mShowAmbient;
+    public boolean isOnAmbient() {
+        return mOnAmbient;
     }
 
     public void setAboveShelf(boolean aboveShelf) {
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 0110610..4963a0c 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
@@ -725,7 +725,7 @@
     }
 
     public int getMaxHeight() {
-        if (mContainingNotification.isShowingAmbient()) {
+        if (mContainingNotification.isOnAmbient()) {
             return getShowingAmbientView().getHeight();
         } else if (mExpandedChild != null) {
             return getViewHeight(VISIBLE_TYPE_EXPANDED)
@@ -752,7 +752,7 @@
     }
 
     public int getMinHeight(boolean likeGroupExpanded) {
-        if (mContainingNotification.isShowingAmbient()) {
+        if (mContainingNotification.isOnAmbient()) {
             return getShowingAmbientView().getHeight();
         } else if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
             return getViewHeight(VISIBLE_TYPE_CONTRACTED);
@@ -1039,7 +1039,7 @@
      * @return one of the static enum types in this view, calculated form the current state
      */
     public int calculateVisibleType() {
-        if (mContainingNotification.isShowingAmbient()) {
+        if (mContainingNotification.isOnAmbient()) {
             if (mIsChildInGroup && mAmbientSingleLineChild != null) {
                 return VISIBLE_TYPE_AMBIENT_SINGLELINE;
             } else if (mAmbientChild != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 9e2331f..903c272 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -103,8 +103,15 @@
     };
 
     private OnClickListener mOnStopOrMinimizeNotifications = v -> {
-        mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
-        swapContent(false);
+        Runnable saveImportance = () -> {
+            mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
+            swapContent(false);
+        };
+        if (mCheckSaveListener != null) {
+            mCheckSaveListener.checkSave(saveImportance, mSbn);
+        } else {
+            saveImportance.run();
+        }
     };
 
     private OnClickListener mOnUndo = v -> {
@@ -304,15 +311,7 @@
 
     private void saveImportance() {
         if (!mIsNonblockable) {
-            // Only go through the lock screen/bouncer if the user hit 'Stop notifications'.
-            // Otherwise, update the importance immediately.
-            if (mCheckSaveListener != null
-                    && NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS.equals(
-                            mExitReason)) {
-                mCheckSaveListener.checkSave(this::updateImportance, mSbn);
-            } else {
-                updateImportance();
-            }
+            updateImportance();
         }
     }
 
@@ -523,6 +522,11 @@
         return getHeight();
     }
 
+    @VisibleForTesting
+    public boolean isAnimating() {
+        return mExpandAnimation != null && mExpandAnimation.isRunning();
+    }
+
     /**
      * Runnable to either update the given channel (with a new importance value) or, if no channel
      * is provided, update notifications enabled state for the package.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index dec88d4..7e60c4b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -16,14 +16,13 @@
 
 package com.android.systemui.statusbar.notification.row;
 
-import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
-
 import java.util.ArrayList;
 
+import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
+
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.AlphaOptimizedImageView;
 import com.android.systemui.statusbar.notification.row.NotificationGuts.GutsContent;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -38,25 +37,21 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.Log;
 import android.service.notification.StatusBarNotification;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.FrameLayout.LayoutParams;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnClickListener,
         ExpandableNotificationRow.LayoutListener {
 
     private static final boolean DEBUG = false;
     private static final String TAG = "swipe";
 
-    private static final int ICON_ALPHA_ANIM_DURATION = 200;
-    private static final long SHOW_MENU_DELAY = 60;
-    private static final long SWIPE_MENU_TIMING = 200;
-
     // Notification must be swiped at least this fraction of a single menu item to show menu
     private static final float SWIPED_FAR_ENOUGH_MENU_FRACTION = 0.25f;
     private static final float SWIPED_FAR_ENOUGH_MENU_UNCLEARABLE_FRACTION = 0.15f;
@@ -65,6 +60,9 @@
     // menu item to snap back to menu (else it will cover the menu or it'll be dismissed)
     private static final float SWIPED_BACK_ENOUGH_TO_COVER_FRACTION = 0.2f;
 
+    private static final int ICON_ALPHA_ANIM_DURATION = 200;
+    private static final long SHOW_MENU_DELAY = 60;
+
     private ExpandableNotificationRow mParent;
 
     private Context mContext;
@@ -89,22 +87,20 @@
     private int[] mIconLocation = new int[2];
     private int[] mParentLocation = new int[2];
 
-    private float mHorizSpaceForIcon = -1;
+    private int mHorizSpaceForIcon = -1;
     private int mVertSpaceForIcons = -1;
     private int mIconPadding = -1;
     private int mSidePadding;
 
     private float mAlpha = 0f;
-    private float mPrevX;
 
     private CheckForDrag mCheckForDrag;
     private Handler mHandler;
 
-    private boolean mMenuSnappedTo;
+    private boolean mMenuSnapped;
     private boolean mMenuSnappedOnLeft;
     private boolean mShouldShowMenu;
 
-    private NotificationSwipeActionHelper mSwipeHelper;
     private boolean mIsUserTouching;
 
     public NotificationMenuRow(Context context) {
@@ -134,9 +130,34 @@
         return mSnoozeItem;
     }
 
-    @Override
-    public void setSwipeActionHelper(NotificationSwipeActionHelper helper) {
-        mSwipeHelper = helper;
+    @VisibleForTesting
+    protected ExpandableNotificationRow getParent() {
+        return mParent;
+    }
+
+    @VisibleForTesting
+    protected boolean isMenuOnLeft() {
+        return mOnLeft;
+    }
+
+    @VisibleForTesting
+    protected boolean isMenuSnappedOnLeft() {
+        return mMenuSnappedOnLeft;
+    }
+
+    @VisibleForTesting
+    protected boolean isMenuSnapped() {
+        return mMenuSnapped;
+    }
+
+    @VisibleForTesting
+    protected boolean isDismissing() {
+        return mDismissing;
+    }
+
+    @VisibleForTesting
+    protected boolean isSnapping() {
+        return mSnapping;
     }
 
     @Override
@@ -155,17 +176,37 @@
         return mAlpha > 0;
     }
 
+    @VisibleForTesting
+    protected boolean isUserTouching() {
+        return mIsUserTouching;
+    }
+
+    @Override
+    public boolean shouldShowMenu() {
+        return mShouldShowMenu;
+    }
+
     @Override
     public View getMenuView() {
         return mMenuContainer;
     }
 
+    @VisibleForTesting
+    protected float getTranslation() {
+        return mTranslation;
+    }
+
     @Override
     public void resetMenu() {
         resetState(true);
     }
 
     @Override
+    public void onTouchEnd() {
+        mIsUserTouching = false;
+    }
+
+    @Override
     public void onNotificationUpdated(StatusBarNotification sbn) {
         if (mMenuContainer == null) {
             // Menu hasn't been created yet, no need to do anything.
@@ -222,9 +263,7 @@
             mIconsPlaced = false;
             setMenuLocation();
             if (!mIsUserTouching) {
-                // If the # of items showing changed we need to update the snap position
-                showMenu(mParent, mOnLeft ? getSpaceForMenu() : -getSpaceForMenu(),
-                        0 /* velocity */);
+                onSnapOpen();
             }
         }
     }
@@ -236,7 +275,7 @@
         mAnimating = false;
         mSnapping = false;
         mDismissing = false;
-        mMenuSnappedTo = false;
+        mMenuSnapped = false;
         setMenuLocation();
         if (mMenuListener != null && notify) {
             mMenuListener.onMenuReset(mParent);
@@ -244,185 +283,102 @@
     }
 
     @Override
-    public boolean onTouchEvent(View view, MotionEvent ev, float velocity) {
-        final int action = ev.getActionMasked();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mSnapping = false;
-                if (mFadeAnimator != null) {
-                    mFadeAnimator.cancel();
-                }
-                mHandler.removeCallbacks(mCheckForDrag);
+    public void onTouchMove(float delta) {
+        mSnapping = false;
+
+        if (!isTowardsMenu(delta) && isMenuLocationChange()) {
+            // Don't consider it "snapped" if location has changed.
+            mMenuSnapped = false;
+
+            // Changed directions, make sure we check to fade in icon again.
+            if (!mHandler.hasCallbacks(mCheckForDrag)) {
+                // No check scheduled, set null to schedule a new one.
                 mCheckForDrag = null;
-                mPrevX = ev.getRawX();
-                mIsUserTouching = true;
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                mSnapping = false;
-                float diffX = ev.getRawX() - mPrevX;
-                mPrevX = ev.getRawX();
-                if (!isTowardsMenu(diffX) && isMenuLocationChange()) {
-                    // Don't consider it "snapped" if location has changed.
-                    mMenuSnappedTo = false;
-
-                    // Changed directions, make sure we check to fade in icon again.
-                    if (!mHandler.hasCallbacks(mCheckForDrag)) {
-                        // No check scheduled, set null to schedule a new one.
-                        mCheckForDrag = null;
-                    } else {
-                        // Check scheduled, reset alpha and update location; check will fade it in
-                        setMenuAlpha(0f);
-                        setMenuLocation();
-                    }
-                }
-                if (mShouldShowMenu
-                        && !NotificationStackScrollLayout.isPinnedHeadsUp(view)
-                        && !mParent.areGutsExposed()
-                        && !mParent.isDark()
-                        && (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag))) {
-                    // Only show the menu if we're not a heads up view and guts aren't exposed.
-                    mCheckForDrag = new CheckForDrag();
-                    mHandler.postDelayed(mCheckForDrag, SHOW_MENU_DELAY);
-                }
-                break;
-
-            case MotionEvent.ACTION_UP:
-                mIsUserTouching = false;
-                return handleUpEvent(ev, view, velocity);
-            case MotionEvent.ACTION_CANCEL:
-                mIsUserTouching = false;
-                cancelDrag();
-                return false;
-        }
-        return false;
-    }
-
-    private boolean handleUpEvent(MotionEvent ev, View animView, float velocity) {
-        // If the menu should not be shown, then there is no need to check if the a swipe
-        // should result in a snapping to the menu. As a result, just check if the swipe
-        // was enough to dismiss the notification.
-        if (!mShouldShowMenu) {
-            if (mSwipeHelper.isDismissGesture(ev)) {
-                dismiss(animView, velocity);
             } else {
-                snapBack(animView, velocity);
+                // Check scheduled, reset alpha and update location; check will fade it in
+                setMenuAlpha(0f);
+                setMenuLocation();
             }
-            return true;
         }
-
-        final boolean gestureTowardsMenu = isTowardsMenu(velocity);
-        final boolean gestureFastEnough =
-                mSwipeHelper.getMinDismissVelocity() <= Math.abs(velocity);
-        final boolean gestureFarEnough =
-                mSwipeHelper.swipedFarEnough(mTranslation, mParent.getWidth());
-        final double timeForGesture = ev.getEventTime() - ev.getDownTime();
-        final boolean showMenuForSlowOnGoing = !mParent.canViewBeDismissed()
-                && timeForGesture >= SWIPE_MENU_TIMING;
-        final float menuSnapTarget = mOnLeft ? getSpaceForMenu() : -getSpaceForMenu();
-
-        if (DEBUG) {
-            Log.d(TAG, "mTranslation= " + mTranslation
-                    + " mAlpha= " + mAlpha
-                    + " velocity= " + velocity
-                    + " mMenuSnappedTo= " + mMenuSnappedTo
-                    + " mMenuSnappedOnLeft= " + mMenuSnappedOnLeft
-                    + " mOnLeft= " + mOnLeft
-                    + " minDismissVel= " + mSwipeHelper.getMinDismissVelocity()
-                    + " isDismissGesture= " + mSwipeHelper.isDismissGesture(ev)
-                    + " gestureTowardsMenu= " + gestureTowardsMenu
-                    + " gestureFastEnough= " + gestureFastEnough
-                    + " gestureFarEnough= " + gestureFarEnough);
+        if (mShouldShowMenu
+                && !NotificationStackScrollLayout.isPinnedHeadsUp(getParent())
+                && !mParent.areGutsExposed()
+                && !mParent.isDark()
+                && (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag))) {
+            // Only show the menu if we're not a heads up view and guts aren't exposed.
+            mCheckForDrag = new CheckForDrag();
+            mHandler.postDelayed(mCheckForDrag, SHOW_MENU_DELAY);
         }
-
-        if (mMenuSnappedTo && isMenuVisible() && mMenuSnappedOnLeft == mOnLeft) {
-            // Menu was snapped to previously and we're on the same side, figure out if
-            // we should stick to the menu, snap back into place, or dismiss
-            final float maximumSwipeDistance = mHorizSpaceForIcon
-                    * SWIPED_BACK_ENOUGH_TO_COVER_FRACTION;
-            final float targetLeft = getSpaceForMenu() - maximumSwipeDistance;
-            final float targetRight = mParent.getWidth() * SWIPED_FAR_ENOUGH_SIZE_FRACTION;
-            boolean withinSnapMenuThreshold = mOnLeft
-                    ? mTranslation > targetLeft && mTranslation < targetRight
-                    : mTranslation < -targetLeft && mTranslation > -targetRight;
-            boolean shouldSnapTo = mOnLeft ? mTranslation < targetLeft : mTranslation > -targetLeft;
-            if (DEBUG) {
-                Log.d(TAG, "   withinSnapMenuThreshold= " + withinSnapMenuThreshold
-                        + "   shouldSnapTo= " + shouldSnapTo
-                        + "   targetLeft= " + targetLeft
-                        + "   targetRight= " + targetRight);
-            }
-            if (withinSnapMenuThreshold && !mSwipeHelper.isDismissGesture(ev)) {
-                // Haven't moved enough to unsnap from the menu
-                showMenu(animView, menuSnapTarget, velocity);
-            } else if (mSwipeHelper.isDismissGesture(ev) && !shouldSnapTo) {
-                // Only dismiss if we're not moving towards the menu
-                dismiss(animView, velocity);
-            } else {
-                snapBack(animView, velocity);
-            }
-        } else if (!mSwipeHelper.isFalseGesture(ev)
-                && (swipedEnoughToShowMenu() && (!gestureFastEnough || showMenuForSlowOnGoing))
-                || (gestureTowardsMenu && !mSwipeHelper.isDismissGesture(ev))) {
-            // Menu has not been snapped to previously and this is menu revealing gesture
-            showMenu(animView, menuSnapTarget, velocity);
-        } else if (mSwipeHelper.isDismissGesture(ev) && !gestureTowardsMenu) {
-            dismiss(animView, velocity);
-        } else {
-            snapBack(animView, velocity);
-        }
-        return true;
     }
 
-    private void showMenu(View animView, float targetLeft, float velocity) {
-        mMenuSnappedTo = true;
-        mMenuSnappedOnLeft = mOnLeft;
-        mMenuListener.onMenuShown(animView);
-        mSwipeHelper.snap(animView, targetLeft, velocity);
+    @VisibleForTesting
+    protected void beginDrag() {
+        mSnapping = false;
+        if (mFadeAnimator != null) {
+            mFadeAnimator.cancel();
+        }
+        mHandler.removeCallbacks(mCheckForDrag);
+        mCheckForDrag = null;
+        mIsUserTouching = true;
     }
 
-    private void snapBack(View animView, float velocity) {
+    @Override
+    public void onTouchStart() {
+       beginDrag();
+    }
+
+    @Override
+    public void onSnapOpen() {
+        mMenuSnapped = true;
+        mMenuSnappedOnLeft = isMenuOnLeft();
+        if (mMenuListener != null) {
+            mMenuListener.onMenuShown(getParent());
+        }
+    }
+
+    @Override
+    public void onSnapClosed() {
         cancelDrag();
-        mMenuSnappedTo = false;
+        mMenuSnapped = false;
         mSnapping = true;
-        mSwipeHelper.snap(animView, 0 /* leftTarget */, velocity);
     }
 
-    private void dismiss(View animView, float velocity) {
+    @Override
+    public void onDismiss() {
         cancelDrag();
-        mMenuSnappedTo = false;
+        mMenuSnapped = false;
         mDismissing = true;
-        mSwipeHelper.dismiss(animView, velocity);
     }
 
-    private void cancelDrag() {
+    @VisibleForTesting
+    protected void cancelDrag() {
         if (mFadeAnimator != null) {
             mFadeAnimator.cancel();
         }
         mHandler.removeCallbacks(mCheckForDrag);
     }
 
-    /**
-     * @return whether the notification has been translated enough to show the menu and not enough
-     *         to be dismissed.
-     */
-    private boolean swipedEnoughToShowMenu() {
-        final float multiplier = mParent.canViewBeDismissed()
+    @VisibleForTesting
+    protected float getMinimumSwipeDistance() {
+        final float multiplier = getParent().canViewBeDismissed()
                 ? SWIPED_FAR_ENOUGH_MENU_FRACTION
                 : SWIPED_FAR_ENOUGH_MENU_UNCLEARABLE_FRACTION;
-        final float minimumSwipeDistance = mHorizSpaceForIcon * multiplier;
-        return !mSwipeHelper.swipedFarEnough(0, 0) && isMenuVisible()
-                && (mOnLeft ? mTranslation > minimumSwipeDistance
-                        : mTranslation < -minimumSwipeDistance);
+        return mHorizSpaceForIcon * multiplier;
+    }
+
+    @VisibleForTesting
+    protected float getMaximumSwipeDistance() {
+        return mHorizSpaceForIcon * SWIPED_BACK_ENOUGH_TO_COVER_FRACTION;
     }
 
     /**
      * Returns whether the gesture is towards the menu location or not.
      */
-    private boolean isTowardsMenu(float movement) {
+    @Override
+    public boolean isTowardsMenu(float movement) {
         return isMenuVisible()
-                && ((mOnLeft && movement <= 0)
-                        || (!mOnLeft && movement >= 0));
+                && ((isMenuOnLeft() && movement <= 0)
+                        || (!isMenuOnLeft() && movement >= 0));
     }
 
     @Override
@@ -445,7 +401,7 @@
     }
 
     @Override
-    public void onHeightUpdate() {
+    public void onParentHeightUpdate() {
         if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
             return;
         }
@@ -460,7 +416,7 @@
     }
 
     @Override
-    public void onTranslationUpdate(float translation) {
+    public void onParentTranslationUpdate(float translation) {
         mTranslation = translation;
         if (mAnimating || !mMenuFadedIn) {
             // Don't adjust when animating, or if the menu hasn't been shown yet.
@@ -492,13 +448,15 @@
         final int x = mIconLocation[0] - mParentLocation[0] + centerX;
         final int y = mIconLocation[1] - mParentLocation[1] + centerY;
         final int index = mMenuContainer.indexOfChild(v);
-        mMenuListener.onMenuClicked(mParent, x, y, mMenuItems.get(index));
+        if (mMenuListener != null) {
+            mMenuListener.onMenuClicked(mParent, x, y, mMenuItems.get(index));
+        }
     }
 
     private boolean isMenuLocationChange() {
         boolean onLeft = mTranslation > mIconPadding;
         boolean onRight = mTranslation < -mIconPadding;
-        if ((mOnLeft && onRight) || (!mOnLeft && onLeft)) {
+        if ((isMenuOnLeft() && onRight) || (!isMenuOnLeft() && onLeft)) {
             return true;
         }
         return false;
@@ -506,7 +464,7 @@
 
     private void setMenuLocation() {
         boolean showOnLeft = mTranslation > 0;
-        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
+        if ((mIconsPlaced && showOnLeft == isMenuOnLeft()) || isSnapping() || mMenuContainer == null
                 || !mMenuContainer.isAttachedToWindow()) {
             // Do nothing
             return;
@@ -522,7 +480,8 @@
         mIconsPlaced = true;
     }
 
-    private void setMenuAlpha(float alpha) {
+    @VisibleForTesting
+    protected void setMenuAlpha(float alpha) {
         mAlpha = alpha;
         if (mMenuContainer == null) {
             return;
@@ -542,7 +501,8 @@
     /**
      * Returns the horizontal space in pixels required to display the menu.
      */
-    private float getSpaceForMenu() {
+    @VisibleForTesting
+    protected int getSpaceForMenu() {
         return mHorizSpaceForIcon * mMenuContainer.getChildCount();
     }
 
@@ -646,12 +606,71 @@
             parent.addView(menuView);
             menuView.setOnClickListener(this);
             FrameLayout.LayoutParams lp = (LayoutParams) menuView.getLayoutParams();
-            lp.width = (int) mHorizSpaceForIcon;
-            lp.height = (int) mHorizSpaceForIcon;
+            lp.width = mHorizSpaceForIcon;
+            lp.height = mHorizSpaceForIcon;
             menuView.setLayoutParams(lp);
         }
     }
 
+    @VisibleForTesting
+    /**
+     * Determine the minimum offset below which the menu should snap back closed.
+     */
+    protected float getSnapBackThreshold() {
+        return getSpaceForMenu() - getMaximumSwipeDistance();
+    }
+
+    /**
+     * Determine the maximum offset above which the parent notification should be dismissed.
+     * @return
+     */
+    @VisibleForTesting
+    protected float getDismissThreshold() {
+        return getParent().getWidth() * SWIPED_FAR_ENOUGH_SIZE_FRACTION;
+    }
+
+    @Override
+    public boolean isWithinSnapMenuThreshold() {
+        float translation = getTranslation();
+        float snapBackThreshold = getSnapBackThreshold();
+        float targetRight = getDismissThreshold();
+        return isMenuOnLeft()
+                ? translation > snapBackThreshold && translation < targetRight
+                : translation < -snapBackThreshold && translation > -targetRight;
+    }
+
+    @Override
+    public boolean isSwipedEnoughToShowMenu() {
+        final float minimumSwipeDistance = getMinimumSwipeDistance();
+        final float translation = getTranslation();
+        return isMenuVisible() && (isMenuOnLeft() ?
+                translation > minimumSwipeDistance
+                : translation < -minimumSwipeDistance);
+    }
+
+    @Override
+    public int getMenuSnapTarget() {
+        return isMenuOnLeft() ? getSpaceForMenu() : -getSpaceForMenu();
+    }
+
+    @Override
+    public boolean shouldSnapBack() {
+        float translation = getTranslation();
+        float targetLeft = getSnapBackThreshold();
+        return isMenuOnLeft() ? translation < targetLeft : translation > -targetLeft;
+    }
+
+    @Override
+    public boolean isSnappedAndOnSameSide() {
+        return isMenuSnapped() && isMenuVisible()
+                && isMenuSnappedOnLeft() == isMenuOnLeft();
+    }
+
+    @Override
+    public boolean canBeDismissed() {
+        return getParent().canViewBeDismissed();
+    }
+
     public static class NotificationMenuItem implements MenuItem {
         View mMenuView;
         GutsContent mGutsContent;
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 15eaaac..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
@@ -20,14 +20,15 @@
 import android.content.Context;
 import android.view.View;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 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.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.ArrayList;
 
@@ -44,7 +45,7 @@
     private int mSpeedBumpIndex = -1;
     private boolean mDark;
     private boolean mHideSensitive;
-    private HeadsUpManager mHeadsUpManager;
+    private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
     private float mStackTranslation;
     private int mLayoutHeight;
     private int mTopPadding;
@@ -207,10 +208,6 @@
         mSpeedBumpIndex = shelfIndex;
     }
 
-    public void setHeadsUpManager(HeadsUpManager headsUpManager) {
-        mHeadsUpManager = headsUpManager;
-    }
-
     public float getStackTranslation() {
         return mStackTranslation;
     }
@@ -334,10 +331,10 @@
     }
 
     public boolean isPulsing(NotificationData.Entry entry) {
-        if (!mPulsing || mHeadsUpManager == null) {
+        if (!mPulsing || mAmbientPulseManager == null) {
             return false;
         }
-        return mHeadsUpManager.getAllEntries().anyMatch(e -> (e == entry));
+        return mAmbientPulseManager.isAlerting(entry.key);
     }
 
     public boolean isPanelTracking() {
@@ -429,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/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 3d44e3c..da089b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -213,7 +213,7 @@
             // calculated correctly as they are used to calculate how many we can fit on the screen.
             boolean isOverflow = i == overflowIndex;
             child.setSingleLineWidthIndention(isOverflow && mOverflowNumber != null &&
-                    !mContainingNotification.isShowingAmbient()
+                    !mContainingNotification.isOnAmbient()
                     ? mOverflowNumber.getMeasuredWidth() : 0);
             child.measure(widthMeasureSpec, newHeightSpec);
             // layout the divider
@@ -406,7 +406,7 @@
         if (childCount > maxAllowedVisibleChildren) {
             int number = childCount - maxAllowedVisibleChildren;
             mOverflowNumber = mHybridGroupManager.bindOverflowNumber(mOverflowNumber, number);
-            if (mContainingNotification.isShowingAmbient()) {
+            if (mContainingNotification.isOnAmbient()) {
                 ExpandableNotificationRow overflowView = mChildren.get(0);
                 HybridNotificationView ambientSingleLineView = overflowView == null ? null
                         : overflowView.getAmbientSingleLineView();
@@ -522,7 +522,7 @@
         if (mUserLocked) {
             expandFactor = getGroupExpandFraction();
         }
-        boolean childrenExpanded = mChildrenExpanded || mContainingNotification.isShowingAmbient();
+        boolean childrenExpanded = mChildrenExpanded || mContainingNotification.isOnAmbient();
         for (int i = 0; i < childCount; i++) {
             if (visibleChildren >= maxAllowedVisibleChildren) {
                 break;
@@ -641,7 +641,7 @@
                     getMaxAllowedVisibleChildren(true /* likeCollapsed */), childCount) - 1);
             mGroupOverFlowState.copyFrom(resultState.getViewStateForView(overflowView));
 
-            if (mContainingNotification.isShowingAmbient()) {
+            if (mContainingNotification.isOnAmbient()) {
                 mGroupOverFlowState.alpha = 0.0f;
             } else if (!mChildrenExpanded) {
                 HybridNotificationView alignView = overflowView.getSingleLineView();
@@ -710,7 +710,7 @@
 
     @VisibleForTesting
     int getMaxAllowedVisibleChildren(boolean likeCollapsed) {
-        if (mContainingNotification.isShowingAmbient()) {
+        if (mContainingNotification.isOnAmbient()) {
             return NUMBER_OF_CHILDREN_WHEN_AMBIENT;
         }
         if (!likeCollapsed && (mChildrenExpanded || mContainingNotification.isUserLocked())
@@ -900,7 +900,7 @@
         return mCurrentHeader;
     }
 
-    public void notifyShowAmbientChanged() {
+    public void notifyDozingStateChanged() {
         updateHeaderVisibility(false);
         updateGroupOverflow();
     }
@@ -970,7 +970,7 @@
 
     private ViewGroup calculateDesiredHeader() {
         ViewGroup desiredHeader;
-        if (mContainingNotification.isShowingAmbient()) {
+        if (mContainingNotification.isOnAmbient()) {
             desiredHeader = mNotificationHeaderAmbient;
         } else if (showingAsLowPriority()) {
             desiredHeader = mNotificationHeaderLowPriority;
@@ -1126,7 +1126,7 @@
     }
 
     public int getMinHeight() {
-        return getMinHeight(mContainingNotification.isShowingAmbient()
+        return getMinHeight(mContainingNotification.isOnAmbient()
                 ? NUMBER_OF_CHILDREN_WHEN_AMBIENT
                 : NUMBER_OF_CHILDREN_WHEN_COLLAPSED, false /* likeHighPriority */);
     }
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 52844fe..9ddab7c 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,8 +25,6 @@
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.FloatRange;
 import android.annotation.Nullable;
 import android.app.WallpaperManager;
 import android.content.Context;
@@ -41,7 +39,6 @@
 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;
@@ -83,12 +80,10 @@
 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;
@@ -110,11 +105,14 @@
 import com.android.systemui.statusbar.notification.row.NotificationGuts;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 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.StatusBarStateController;
 import com.android.systemui.statusbar.notification.FakeShadowView;
 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.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
@@ -134,8 +132,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.annotation.ShadeViewRefactor;
-import java.lang.annotation.ShadeViewRefactor.RefactorComponent;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -147,11 +143,9 @@
  * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
  */
 public class NotificationStackScrollLayout extends ViewGroup
-        implements Callback, ExpandHelper.Callback, ScrollAdapter,
-        OnHeightChangedListener, OnGroupChangeListener,
-        OnMenuEventListener, VisibilityLocationProvider,
-        NotificationListContainer, ConfigurationListener, DragDownCallback, AnimationStateHandler,
-        Dumpable {
+        implements ExpandHelper.Callback, ScrollAdapter, OnHeightChangedListener,
+        OnGroupChangeListener, VisibilityLocationProvider, NotificationListContainer,
+        ConfigurationListener, DragDownCallback, AnimationStateHandler, Dumpable {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
@@ -165,7 +159,7 @@
     private static final int INVALID_POINTER = -1;
 
     private ExpandHelper mExpandHelper;
-    private NotificationSwipeHelper mSwipeHelper;
+    private final NotificationSwipeHelper mSwipeHelper;
     private boolean mSwipingInProgress;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
     private final Paint mBackgroundPaint = new Paint();
@@ -292,10 +286,6 @@
      */
     private int mMaxScrollAfterExpand;
     private ExpandableNotificationRow.LongPressListener mLongPressListener;
-
-    private NotificationMenuRowPlugin mCurrMenuRow;
-    private View mTranslatingParentView;
-    private View mMenuExposedView;
     boolean mCheckForLeavebehind;
 
     /**
@@ -467,6 +457,9 @@
     private Interpolator mDarkXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
     private NotificationPanelView mNotificationPanel;
 
+    private final NotificationGutsManager
+            mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);
+
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public NotificationStackScrollLayout(Context context) {
         this(context, null);
@@ -496,7 +489,8 @@
                 minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollAdapter(this);
-        mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, this, getContext());
+        mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, new SwipeHelperCallback(),
+                getContext(), new NotificationMenuListener());
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
         initView(context);
         mFalsingManager = FalsingManager.getInstance(context);
@@ -620,7 +614,8 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class)
+                .addListener(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
@@ -639,41 +634,6 @@
     }
 
     @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onMenuClicked(View view, int x, int y, MenuItem item) {
-        if (mLongPressListener == null) {
-            return;
-        }
-        if (view instanceof ExpandableNotificationRow) {
-            ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_TOUCH_GEAR,
-                    row.getStatusBarNotification().getPackageName());
-        }
-        mLongPressListener.onLongPress(view, x, y, item);
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onMenuReset(View row) {
-        if (mTranslatingParentView != null && row == mTranslatingParentView) {
-            mMenuExposedView = null;
-            mTranslatingParentView = null;
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onMenuShown(View row) {
-        mMenuExposedView = mTranslatingParentView;
-        if (row instanceof ExpandableNotificationRow) {
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_REVEAL_GEAR,
-                    ((ExpandableNotificationRow) row).getStatusBarNotification()
-                            .getPackageName());
-        }
-        mSwipeHelper.onMenuShown(row);
-    }
-
-    @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void onUiModeChanged() {
         mBgColor = mContext.getColor(R.color.notification_shade_background_color);
@@ -1295,111 +1255,6 @@
         mQsContainer = qsContainer;
     }
 
-    /**
-     * Handles cleanup after the given {@code view} has been fully swiped out (including
-     * 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()) {
-            handleChildViewDismissed(view);
-        }
-        ViewGroup transientContainer = row.getTransientContainer();
-        if (transientContainer != null) {
-            transientContainer.removeTransientView(view);
-        }
-    }
-
-    /**
-     * Starts up notification dismiss and tells the notification, if any, to remove itself from
-     * layout.
-     *
-     * @param view view (e.g. notification) to dismiss from the layout
-     */
-
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    private void handleChildViewDismissed(View view) {
-        if (mDismissAllInProgress) {
-            return;
-        }
-
-        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.
-            mDragAnimPendingChildren.remove(view);
-        }
-        mAmbientState.onDragFinished(view);
-        updateContinuousShadowDrawing();
-
-        if (view instanceof ExpandableNotificationRow) {
-            ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-            if (row.isHeadsUp()) {
-                mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey());
-            }
-            isBlockingHelperShown =
-                    row.performDismissWithBlockingHelper(false /* fromAccessibility */);
-        }
-
-        if (!isBlockingHelperShown) {
-            mSwipedOutViews.add(view);
-        }
-        mFalsingManager.onNotificationDismissed();
-        if (mFalsingManager.shouldEnforceBouncer()) {
-            mStatusBar.executeRunnableDismissingKeyguard(
-                    null,
-                    null /* cancelAction */,
-                    false /* dismissShade */,
-                    true /* afterKeyguardGone */,
-                    false /* deferred */);
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void onChildSnappedBack(View animView, float targetLeft) {
-        mAmbientState.onDragFinished(animView);
-        updateContinuousShadowDrawing();
-        if (!mDragAnimPendingChildren.contains(animView)) {
-            if (mAnimationsEnabled) {
-                mSnappedBackChildren.add(animView);
-                mNeedsAnimation = true;
-            }
-            requestChildrenUpdate();
-        } else {
-            // We start the swipe and snap back in the same frame, we don't want any animation
-            mDragAnimPendingChildren.remove(animView);
-        }
-        if (mCurrMenuRow != null && targetLeft == 0) {
-            mCurrMenuRow.resetMenu();
-            mCurrMenuRow = null;
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) {
-        // Returning true prevents alpha fading.
-        return !mFadeNotificationsOnDismiss;
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onBeginDrag(View v) {
-        mFalsingManager.onNotificatonStartDismissing();
-        setSwipingInProgress(true);
-        mAmbientState.onBeginDrag(v);
-        updateContinuousShadowDrawing();
-        if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
-            mDragAnimPendingChildren.add(v);
-            mNeedsAnimation = true;
-        }
-        requestChildrenUpdate();
-    }
-
     @ShadeViewRefactor(RefactorComponent.ADAPTER)
     public static boolean isPinnedHeadsUp(View v) {
         if (v instanceof ExpandableNotificationRow) {
@@ -1418,41 +1273,6 @@
         return false;
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onDragCancelled(View v) {
-        mFalsingManager.onNotificatonStopDismissing();
-        setSwipingInProgress(false);
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public float getFalsingThresholdFactor() {
-        return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public View getChildAtPosition(MotionEvent ev) {
-        View child = getChildAtPosition(ev.getX(), ev.getY());
-        if (child instanceof ExpandableNotificationRow) {
-            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-            ExpandableNotificationRow parent = row.getNotificationParent();
-            if (parent != null && parent.areChildrenExpanded()
-                    && (parent.areGutsExposed()
-                    || mMenuExposedView == parent
-                    || (parent.getNotificationChildren().size() == 1
-                    && parent.isClearable()))) {
-                // In this case the group is expanded and showing the menu for the
-                // group, further interaction should apply to the group, not any
-                // child notifications so we use the parent of the child. We also do the same
-                // if we only have a single child.
-                child = parent;
-            }
-        }
-        return child;
-    }
-
     @ShadeViewRefactor(RefactorComponent.INPUT)
     public ExpandableView getClosestChildAtRawPosition(float touchX, float touchY) {
         getLocationOnScreen(mTempInt2);
@@ -1696,18 +1516,11 @@
         return mScrollingEnabled;
     }
 
-    @Override
     @ShadeViewRefactor(RefactorComponent.ADAPTER)
-    public boolean canChildBeDismissed(View v) {
+    private boolean canChildBeDismissed(View v) {
         return StackScrollAlgorithm.canChildBeDismissed(v);
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean isAntiFalsingNeeded() {
-        return onKeyguard();
-    }
-
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private boolean onKeyguard() {
         return mStatusBarState == StatusBarState.KEYGUARD;
@@ -1787,8 +1600,8 @@
         }
 
         // Check if we need to clear any snooze leavebehinds
-        NotificationGuts guts = mStatusBar.getGutsManager().getExposedGuts();
-        if (guts != null && !isTouchInView(ev, guts)
+        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
+        if (guts != null && !NotificationSwipeHelper.isTouchInView(ev, guts)
                 && guts.getGutsContent() instanceof NotificationSnooze) {
             NotificationSnooze ns = (NotificationSnooze) guts.getGutsContent();
             if ((ns.isExpanded() && isCancelOrUp)
@@ -3013,11 +2826,11 @@
         }
         // Check if we need to clear any snooze leavebehinds
         boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
-        NotificationGuts guts = mStatusBar.getGutsManager().getExposedGuts();
-        if (!isTouchInView(ev, guts) && isUp && !swipeWantsIt && !expandWantsIt
-                && !scrollWantsIt) {
+        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
+        if (!NotificationSwipeHelper.isTouchInView(ev, guts) && isUp && !swipeWantsIt &&
+                !expandWantsIt && !scrollWantsIt) {
             mCheckForLeavebehind = false;
-            mStatusBar.getGutsManager().closeAndSaveGuts(true /* removeLeavebehind */,
+            mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
                     false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
                     false /* resetMenu */);
         }
@@ -3077,8 +2890,8 @@
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     @Override
     public void cleanUpViewState(View child) {
-        if (child == mTranslatingParentView) {
-            mTranslatingParentView = null;
+        if (child == mSwipeHelper.getTranslatingParentView()) {
+            mSwipeHelper.clearTranslatingParentView();
         }
         mCurrentStackScrollState.removeViewStateForView(child);
     }
@@ -3918,12 +3731,14 @@
         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 */);
         }
     }
 
@@ -3986,7 +3801,7 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void checkSnoozeLeavebehind() {
         if (mCheckForLeavebehind) {
-            mStatusBar.getGutsManager().closeAndSaveGuts(true /* removeLeavebehind */,
+            mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
                     false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
                     false /* resetMenu */);
             mCheckForLeavebehind = false;
@@ -4053,6 +3868,7 @@
     public void onPanelTrackingStarted() {
         mPanelTracking = true;
         mAmbientState.setPanelTracking(true);
+        resetExposedMenuView(true /* animate */, true /* force */);
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4068,7 +3884,7 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
-    private void setIsExpanded(boolean isExpanded) {
+    public void setIsExpanded(boolean isExpanded) {
         boolean changed = isExpanded != mIsExpanded;
         mIsExpanded = isExpanded;
         mStackScrollAlgorithm.setIsExpanded(isExpanded);
@@ -4248,8 +4064,9 @@
         mDimAnimator.addUpdateListener(mDimUpdateListener);
         mDimAnimator.start();
     }
+
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setHideSensitive(boolean hideSensitive, boolean animate) {
+    private void setHideSensitive(boolean hideSensitive, boolean animate) {
         if (hideSensitive != mAmbientState.isHideSensitive()) {
             int childCount = getChildCount();
             for (int i = 0; i < childCount; i++) {
@@ -4454,8 +4271,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);
@@ -4466,6 +4285,9 @@
                 mIconAreaController.setFullyDark(nowFullyDark);
             }
         }
+        if (!wasDarkAtAll && nowDarkAtAll) {
+            resetExposedMenuView(true /* animate */, true /* animate */);
+        }
         updateAlgorithmHeightAndPadding();
         updateBackgroundDimming();
         updatePanelTranslation();
@@ -4826,7 +4648,6 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
         mHeadsUpManager = headsUpManager;
-        mAmbientState.setHeadsUpManager(headsUpManager);
         mHeadsUpManager.addListener(mRoundnessManager);
         mHeadsUpManager.setAnimationStateHandler(this);
     }
@@ -5008,8 +4829,12 @@
     private void setStatusBarState(int statusBarState) {
         mStatusBarState = statusBarState;
         mAmbientState.setStatusBarState(statusBarState);
+    }
+
+    private void onStatePostChange() {
         boolean onKeyguard = onKeyguard();
         boolean publicMode = mLockscreenUserManager.isAnyProfilePublicMode();
+
         if (mHeadsUpAppearanceController != null) {
             mHeadsUpAppearanceController.setPublicMode(publicMode);
         }
@@ -5026,6 +4851,8 @@
         updateFooter();
         updateChildren();
         onUpdateRowStates();
+
+        mEntryManager.updateNotifications();
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5236,8 +5063,8 @@
         setFooterView(footerView);
     }
 
-  @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-  private void inflateEmptyShadeView() {
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    private void inflateEmptyShadeView() {
         EmptyShadeView view = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_no_notifications, this, false);
         view.setText(R.string.empty_shade_text);
@@ -5268,8 +5095,8 @@
         mScrimController.setNotificationCount(getNotGoneChildCount());
     }
 
-  @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-  public void setNotificationPanel(NotificationPanelView notificationPanelView) {
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    public void setNotificationPanel(NotificationPanelView notificationPanelView) {
         mNotificationPanel = notificationPanelView;
     }
 
@@ -5287,226 +5114,29 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public interface OnOverscrollTopChangedListener {
 
-        /**
-         * Notifies a listener that the overscroll has changed.
-         *
-         * @param amount         the amount of overscroll, in pixels
-         * @param isRubberbanded if true, this is a rubberbanded overscroll; if false, this is an
-         *                       unrubberbanded motion to directly expand overscroll view (e.g
-         *                       expand
-         *                       QS)
-         */
-        void onOverscrollTopChanged(float amount, boolean isRubberbanded);
+    /**
+     * Notifies a listener that the overscroll has changed.
+     *
+     * @param amount         the amount of overscroll, in pixels
+     * @param isRubberbanded if true, this is a rubberbanded overscroll; if false, this is an
+     *                       unrubberbanded motion to directly expand overscroll view (e.g
+     *                       expand
+     *                       QS)
+     */
+    void onOverscrollTopChanged(float amount, boolean isRubberbanded);
 
-        /**
-         * Notify a listener that the scroller wants to escape from the scrolling motion and
-         * start a fling animation to the expanded or collapsed overscroll view (e.g expand the QS)
-         *
-         * @param velocity The velocity that the Scroller had when over flinging
-         * @param open     Should the fling open or close the overscroll view.
-         */
-        void flingTopOverscroll(float velocity, boolean open);
-    }
+    /**
+     * Notify a listener that the scroller wants to escape from the scrolling motion and
+     * start a fling animation to the expanded or collapsed overscroll view (e.g expand the QS)
+     *
+     * @param velocity The velocity that the Scroller had when over flinging
+     * @param open     Should the fling open or close the overscroll view.
+     */
+    void flingTopOverscroll(float velocity, boolean open);
+  }
 
-  @ShadeViewRefactor(RefactorComponent.INPUT)
-  private class NotificationSwipeHelper extends SwipeHelper
-            implements NotificationSwipeActionHelper {
-        private static final long COVER_MENU_DELAY = 4000;
-        private Runnable mFalsingCheck;
-        private Handler mHandler;
-
-        public NotificationSwipeHelper(int swipeDirection, Callback callback, Context context) {
-            super(swipeDirection, callback, context);
-            mHandler = new Handler();
-            mFalsingCheck = new Runnable() {
-                @Override
-                public void run() {
-                    resetExposedMenuView(true /* animate */, true /* force */);
-                }
-            };
-        }
-
-        @Override
-        public void onDownUpdate(View currView, MotionEvent ev) {
-            mTranslatingParentView = currView;
-            if (mCurrMenuRow != null) {
-                mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
-            }
-            mCurrMenuRow = null;
-            mHandler.removeCallbacks(mFalsingCheck);
-
-            // Slide back any notifications that might be showing a menu
-            resetExposedMenuView(true /* animate */, false /* force */);
-
-            if (currView instanceof ExpandableNotificationRow) {
-                ExpandableNotificationRow row = (ExpandableNotificationRow) currView;
-
-                if (row.getEntry().hasFinishedInitialization()) {
-                    mCurrMenuRow = row.createMenu();
-                    mCurrMenuRow.setSwipeActionHelper(NotificationSwipeHelper.this);
-                    mCurrMenuRow.setMenuClickListener(NotificationStackScrollLayout.this);
-                    mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
-                }
-            }
-        }
-
-        @Override
-        public void onMoveUpdate(View view, MotionEvent ev, float translation, float delta) {
-            mHandler.removeCallbacks(mFalsingCheck);
-            if (mCurrMenuRow != null) {
-                mCurrMenuRow.onTouchEvent(view, ev, 0 /* velocity */);
-            }
-        }
-
-        @Override
-        public boolean handleUpEvent(MotionEvent ev, View animView, float velocity,
-                float translation) {
-            if (mCurrMenuRow != null) {
-                return mCurrMenuRow.onTouchEvent(animView, ev, velocity);
-            }
-            return false;
-        }
-
-        @Override
-        public void dismissChild(final View view, float velocity,
-                boolean useAccelerateInterpolator) {
-            super.dismissChild(view, velocity, useAccelerateInterpolator);
-            if (mIsExpanded) {
-                // We don't want to quick-dismiss when it's a heads up as this might lead to closing
-                // of the panel early.
-                handleChildViewDismissed(view);
-            }
-            mStatusBar.getGutsManager().closeAndSaveGuts(true /* removeLeavebehind */,
-                    false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
-                    false /* resetMenu */);
-            handleMenuCoveredOrDismissed();
-        }
-
-        @Override
-        public void snapChild(final View animView, final float targetLeft, float velocity) {
-            super.snapChild(animView, targetLeft, velocity);
-            onDragCancelled(animView);
-            if (targetLeft == 0) {
-                handleMenuCoveredOrDismissed();
-            }
-        }
-
-        @Override
-        public void snooze(StatusBarNotification sbn, SnoozeOption snoozeOption) {
-            mStatusBar.setNotificationSnoozed(sbn, snoozeOption);
-        }
-
-        public boolean isFalseGesture(MotionEvent ev) {
-            return super.isFalseGesture(ev);
-        }
-
-        private void handleMenuCoveredOrDismissed() {
-            if (mMenuExposedView != null && mMenuExposedView == mTranslatingParentView) {
-                mMenuExposedView = null;
-            }
-        }
-
-        @Override
-        public Animator getViewTranslationAnimator(View v, float target,
-                AnimatorUpdateListener listener) {
-            if (v instanceof ExpandableNotificationRow) {
-                return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener);
-            } else {
-                return super.getViewTranslationAnimator(v, target, listener);
-            }
-        }
-
-        @Override
-        public void setTranslation(View v, float translate) {
-            ((ExpandableView) v).setTranslation(translate);
-        }
-
-        @Override
-        public float getTranslation(View v) {
-            return ((ExpandableView) v).getTranslation();
-        }
-
-        @Override
-        public void dismiss(View animView, float velocity) {
-            dismissChild(animView, velocity,
-                    !swipedFastEnough(0, 0) /* useAccelerateInterpolator */);
-        }
-
-        @Override
-        public void snap(View animView, float targetLeft, float velocity) {
-            snapChild(animView, targetLeft, velocity);
-        }
-
-        @Override
-        public boolean swipedFarEnough(float translation, float viewSize) {
-            return swipedFarEnough();
-        }
-
-        @Override
-        public boolean swipedFastEnough(float translation, float velocity) {
-            return swipedFastEnough();
-        }
-
-        @Override
-        public float getMinDismissVelocity() {
-            return getEscapeVelocity();
-        }
-
-        public void onMenuShown(View animView) {
-            onDragCancelled(animView);
-
-            // If we're on the lockscreen we want to false this.
-            if (isAntiFalsingNeeded()) {
-                mHandler.removeCallbacks(mFalsingCheck);
-                mHandler.postDelayed(mFalsingCheck, COVER_MENU_DELAY);
-            }
-        }
-
-        public void closeControlsIfOutsideTouch(MotionEvent ev) {
-            NotificationGuts guts = mStatusBar.getGutsManager().getExposedGuts();
-            View view = null;
-            if (guts != null && !guts.getGutsContent().isLeavebehind()) {
-                // Only close visible guts if they're not a leavebehind.
-                view = guts;
-            } else if (mCurrMenuRow != null && mCurrMenuRow.isMenuVisible()
-                    && mTranslatingParentView != null) {
-                // Checking menu
-                view = mTranslatingParentView;
-            }
-            if (view != null && !isTouchInView(ev, view)) {
-                // Touch was outside visible guts / menu notification, close what's visible
-                mStatusBar.getGutsManager().closeAndSaveGuts(false /* removeLeavebehind */,
-                        false /* force */, true /* removeControls */, -1 /* x */, -1 /* y */,
-                        false /* resetMenu */);
-                resetExposedMenuView(true /* animate */, true /* force */);
-            }
-        }
-
-        public void resetExposedMenuView(boolean animate, boolean force) {
-            if (mMenuExposedView == null
-                    || (!force && mMenuExposedView == mTranslatingParentView)) {
-                // If no menu is showing or it's showing for this view we do nothing.
-                return;
-            }
-            final View prevMenuExposedView = mMenuExposedView;
-            if (animate) {
-                Animator anim = getViewTranslationAnimator(prevMenuExposedView,
-                        0 /* leftTarget */, null /* updateListener */);
-                if (anim != null) {
-                    anim.start();
-                }
-            } else if (mMenuExposedView instanceof ExpandableNotificationRow) {
-                ExpandableNotificationRow row = (ExpandableNotificationRow) mMenuExposedView;
-                if (!row.isRemoved()) {
-                    row.resetTranslation();
-                }
-            }
-            mMenuExposedView = null;
-        }
-    }
-
-  @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-  public boolean hasActiveNotifications() {
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    public boolean hasActiveNotifications() {
         return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
     }
 
@@ -5570,8 +5200,8 @@
         return mStatusBarState == StatusBarState.KEYGUARD;
     }
 
-  @ShadeViewRefactor(RefactorComponent.INPUT)
-  public void updateSpeedBumpIndex() {
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void updateSpeedBumpIndex() {
         int speedBumpIndex = 0;
         int currentIndex = 0;
         final int N = getChildCount();
@@ -5591,24 +5221,6 @@
         updateSpeedBumpIndex(speedBumpIndex, noAmbient);
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private boolean isTouchInView(MotionEvent ev, View view) {
-        if (view == null) {
-            return false;
-        }
-        final int height = (view instanceof ExpandableView)
-                ? ((ExpandableView) view).getActualHeight()
-                : view.getHeight();
-        final int rx = (int) ev.getRawX();
-        final int ry = (int) ev.getRawY();
-        view.getLocationOnScreen(mTempInt2);
-        final int x = mTempInt2[0];
-        final int y = mTempInt2[1];
-        Rect rect = new Rect(x, y, x + view.getWidth(), y + height);
-        boolean ret = rect.contains(rx, ry);
-        return ret;
-    }
-
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     private void updateContinuousShadowDrawing() {
         boolean continuousShadowUpdate = mAnimationRunning
@@ -5632,11 +5244,29 @@
 
     @ShadeViewRefactor(RefactorComponent.INPUT)
     public void closeControlsIfOutsideTouch(MotionEvent ev) {
-        mSwipeHelper.closeControlsIfOutsideTouch(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 {
+    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
+    static class AnimationEvent {
 
         static AnimationFilter[] FILTERS = new AnimationFilter[]{
 
@@ -5936,8 +5566,8 @@
         }
     }
 
-  @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
-  private final StateListener mStateListener = new StateListener() {
+    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
+    private final StateListener mStateListener = new StateListener() {
         @Override
         public void onStatePreChange(int oldState, int newState) {
             if (oldState == StatusBarState.SHADE_LOCKED && newState == StatusBarState.KEYGUARD) {
@@ -5949,5 +5579,223 @@
         public void onStateChanged(int newState) {
             setStatusBarState(newState);
         }
+
+        @Override
+        public void onStatePostChange() {
+          NotificationStackScrollLayout.this.onStatePostChange();
+      }
     };
+
+    class NotificationMenuListener implements NotificationMenuRowPlugin.OnMenuEventListener {
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public void onMenuClicked(View view, int x, int y, MenuItem item) {
+            if (mLongPressListener == null) {
+                return;
+            }
+            if (view instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_TOUCH_GEAR,
+                        row.getStatusBarNotification().getPackageName());
+            }
+            mLongPressListener.onLongPress(view, x, y, item);
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public void onMenuReset(View row) {
+            View translatingParentView = mSwipeHelper.getTranslatingParentView();
+            if (translatingParentView != null && row == translatingParentView) {
+                mSwipeHelper.clearExposedMenuView();
+                mSwipeHelper.clearTranslatingParentView();
+            }
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public void onMenuShown(View row) {
+            if (row instanceof ExpandableNotificationRow) {
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_REVEAL_GEAR,
+                        ((ExpandableNotificationRow) row).getStatusBarNotification()
+                                .getPackageName());
+            }
+            mSwipeHelper.onMenuShown(row);
+        }
+    }
+
+    class SwipeHelperCallback implements NotificationSwipeHelper.NotificationCallback {
+        @Override
+        public void onDismiss() {
+            mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
+                    false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
+                    false /* resetMenu */);
+        }
+
+        @Override
+        public void onSnooze(StatusBarNotification sbn,
+                NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
+            mStatusBar.setNotificationSnoozed(sbn, snoozeOption);
+        }
+
+        @Override
+        public boolean isExpanded() {
+            return NotificationStackScrollLayout.this.isExpanded();
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public void onDragCancelled(View v) {
+            mFalsingManager.onNotificatonStopDismissing();
+            setSwipingInProgress(false);
+        }
+
+        /**
+         * Handles cleanup after the given {@code view} has been fully swiped out (including
+         * 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()) {
+                handleChildViewDismissed(view);
+            }
+            ViewGroup transientContainer = row.getTransientContainer();
+            if (transientContainer != null) {
+                transientContainer.removeTransientView(view);
+            }
+        }
+
+        /**
+         * Starts up notification dismiss and tells the notification, if any, to remove itself from
+         * layout.
+         *
+         * @param view view (e.g. notification) to dismiss from the layout
+         */
+
+        @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+        public void handleChildViewDismissed(View view) {
+            if (mDismissAllInProgress) {
+                return;
+            }
+
+            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.
+                mDragAnimPendingChildren.remove(view);
+            }
+            mAmbientState.onDragFinished(view);
+            updateContinuousShadowDrawing();
+
+            if (view instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+                if (row.isHeadsUp()) {
+                    mHeadsUpManager.addSwipedOutNotification(
+                            row.getStatusBarNotification().getKey());
+                }
+                isBlockingHelperShown =
+                        row.performDismissWithBlockingHelper(false /* fromAccessibility */);
+            }
+
+            if (!isBlockingHelperShown) {
+                mSwipedOutViews.add(view);
+            }
+            mFalsingManager.onNotificationDismissed();
+            if (mFalsingManager.shouldEnforceBouncer()) {
+                mStatusBar.executeRunnableDismissingKeyguard(
+                        null,
+                        null /* cancelAction */,
+                        false /* dismissShade */,
+                        true /* afterKeyguardGone */,
+                        false /* deferred */);
+            }
+        }
+
+        @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());
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                ExpandableNotificationRow parent = row.getNotificationParent();
+                if (parent != null && parent.areChildrenExpanded()
+                        && (parent.areGutsExposed()
+                        || mSwipeHelper.getExposedMenuView() == parent
+                        || (parent.getNotificationChildren().size() == 1
+                        && parent.isClearable()))) {
+                    // In this case the group is expanded and showing the menu for the
+                    // group, further interaction should apply to the group, not any
+                    // child notifications so we use the parent of the child. We also do the same
+                    // if we only have a single child.
+                    child = parent;
+                }
+            }
+            return child;
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public void onBeginDrag(View v) {
+            mFalsingManager.onNotificatonStartDismissing();
+            setSwipingInProgress(true);
+            mAmbientState.onBeginDrag(v);
+            updateContinuousShadowDrawing();
+            if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
+                mDragAnimPendingChildren.add(v);
+                mNeedsAnimation = true;
+            }
+            requestChildrenUpdate();
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+        public void onChildSnappedBack(View animView, float targetLeft) {
+            mAmbientState.onDragFinished(animView);
+            updateContinuousShadowDrawing();
+            if (!mDragAnimPendingChildren.contains(animView)) {
+                if (mAnimationsEnabled) {
+                    mSnappedBackChildren.add(animView);
+                    mNeedsAnimation = true;
+                }
+                requestChildrenUpdate();
+            } else {
+                // We start the swipe and snap back in the same frame, we don't want any animation
+                mDragAnimPendingChildren.remove(animView);
+            }
+            NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
+            if (menuRow != null && targetLeft == 0) {
+                menuRow.resetMenu();
+                mSwipeHelper.clearCurrentMenuRow();
+            }
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public boolean updateSwipeProgress(View animView, boolean dismissable,
+                float swipeProgress) {
+            // Returning true prevents alpha fading.
+            return !mFadeNotificationsOnDismiss;
+        }
+
+        @Override
+        @ShadeViewRefactor(RefactorComponent.INPUT)
+        public float getFalsingThresholdFactor() {
+            return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+        }
+
+        @Override
+        public boolean canChildBeDismissed(View v) {
+            return NotificationStackScrollLayout.this.canChildBeDismissed(v);
+        }
+    }
 }
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
new file mode 100644
index 0000000..028957d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the Licen
+ */
+
+
+package com.android.systemui.statusbar.notification.stack;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.SwipeHelper;
+import com.android.systemui.plugins.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
+    protected static final long COVER_MENU_DELAY = 4000;
+    private static final String TAG = "NotificationSwipeHelper";
+    private final Runnable mFalsingCheck;
+    private View mTranslatingParentView;
+    private View mMenuExposedView;
+    private final NotificationCallback mCallback;
+    private final NotificationMenuRowPlugin.OnMenuEventListener mMenuListener;
+
+    private static final long SWIPE_MENU_TIMING = 200;
+
+    private NotificationMenuRowPlugin mCurrMenuRow;
+
+    public NotificationSwipeHelper(int swipeDirection, NotificationCallback callback,
+            Context context, NotificationMenuRowPlugin.OnMenuEventListener menuListener) {
+        super(swipeDirection, callback, context);
+        mMenuListener = menuListener;
+        mCallback = callback;
+        mFalsingCheck = new Runnable() {
+            @Override
+            public void run() {
+                resetExposedMenuView(true /* animate */, true /* force */);
+            }
+        };
+    }
+
+    public View getTranslatingParentView() {
+        return mTranslatingParentView;
+    }
+
+    public void clearTranslatingParentView() { setTranslatingParentView(null); }
+
+    @VisibleForTesting
+    protected void setTranslatingParentView(View view) { mTranslatingParentView = view; };
+
+    public void setExposedMenuView(View view) {
+        mMenuExposedView = view;
+    }
+
+    public void clearExposedMenuView() { setExposedMenuView(null); }
+
+    public void clearCurrentMenuRow() { setCurrentMenuRow(null); }
+
+    public View getExposedMenuView() {
+        return mMenuExposedView;
+    }
+
+    public void setCurrentMenuRow(NotificationMenuRowPlugin menuRow) {
+        mCurrMenuRow = menuRow;
+    }
+
+    public NotificationMenuRowPlugin getCurrentMenuRow() {  return mCurrMenuRow; }
+
+    @VisibleForTesting
+    protected Handler getHandler() { return mHandler; }
+
+    @VisibleForTesting
+    protected Runnable getFalsingCheck() { return mFalsingCheck; };
+
+    @Override
+    public void onDownUpdate(View currView, MotionEvent ev) {
+        mTranslatingParentView = currView;
+        NotificationMenuRowPlugin menuRow = getCurrentMenuRow();
+        if (menuRow != null) {
+            menuRow.onTouchStart();
+        }
+        clearCurrentMenuRow();
+        getHandler().removeCallbacks(getFalsingCheck());
+
+        // Slide back any notifications that might be showing a menu
+        resetExposedMenuView(true /* animate */, false /* force */);
+
+        if (currView instanceof ExpandableNotificationRow) {
+            initializeRow((ExpandableNotificationRow) currView);
+        }
+    }
+
+    @VisibleForTesting
+    protected void initializeRow(ExpandableNotificationRow row) {
+        if (row.getEntry().hasFinishedInitialization()) {
+            mCurrMenuRow = row.createMenu();
+            mCurrMenuRow.setMenuClickListener(mMenuListener);
+            mCurrMenuRow.onTouchStart();
+        }
+    }
+
+    private boolean swipedEnoughToShowMenu(NotificationMenuRowPlugin menuRow) {
+        return !swipedFarEnough() && menuRow.isSwipedEnoughToShowMenu();
+    }
+
+    @Override
+    public void onMoveUpdate(View view, MotionEvent ev, float translation, float delta) {
+        getHandler().removeCallbacks(getFalsingCheck());
+        NotificationMenuRowPlugin menuRow = getCurrentMenuRow();
+        if (menuRow != null) {
+            menuRow.onTouchMove(delta);
+        }
+    }
+
+    @Override
+    public boolean handleUpEvent(MotionEvent ev, View animView, float velocity,
+            float translation) {
+        NotificationMenuRowPlugin menuRow = getCurrentMenuRow();
+        if (menuRow != null) {
+            menuRow.onTouchEnd();
+            handleMenuRowSwipe(ev, animView, velocity, menuRow);
+            return true;
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    protected void handleMenuRowSwipe(MotionEvent ev, View animView, float velocity,
+            NotificationMenuRowPlugin menuRow) {
+        if (!menuRow.shouldShowMenu()) {
+            // If the menu should not be shown, then there is no need to check if the a swipe
+            // should result in a snapping to the menu. As a result, just check if the swipe
+            // was enough to dismiss the notification.
+            if (isDismissGesture(ev)) {
+                dismiss(animView, velocity);
+            } else {
+                snapClosed(animView, velocity);
+                menuRow.onSnapClosed();
+            }
+            return;
+        }
+
+        if (menuRow.isSnappedAndOnSameSide()) {
+            // Menu was snapped to previously and we're on the same side
+            handleSwipeFromSnap(ev, animView, velocity, menuRow);
+        } else {
+            // Menu has not been snapped, or was snapped previously but is now on
+            // the opposite side.
+            handleSwipeFromNonSnap(ev, animView, velocity, menuRow);
+        }
+    }
+
+    private void handleSwipeFromNonSnap(MotionEvent ev, View animView, float velocity,
+            NotificationMenuRowPlugin menuRow) {
+        boolean isDismissGesture = isDismissGesture(ev);
+        final boolean gestureTowardsMenu = menuRow.isTowardsMenu(velocity);
+        final boolean gestureFastEnough = getEscapeVelocity() <= Math.abs(velocity);
+
+        final double timeForGesture = ev.getEventTime() - ev.getDownTime();
+        final boolean showMenuForSlowOnGoing = !menuRow.canBeDismissed()
+                && timeForGesture >= SWIPE_MENU_TIMING;
+
+        if (!isFalseGesture(ev)
+                && (swipedEnoughToShowMenu(menuRow)
+                && (!gestureFastEnough || showMenuForSlowOnGoing))
+                || (gestureTowardsMenu && !isDismissGesture)) {
+            // Menu has not been snapped to previously and this is menu revealing gesture
+            snapOpen(animView, menuRow.getMenuSnapTarget(), velocity);
+            menuRow.onSnapOpen();
+        } else if (isDismissGesture(ev) && !gestureTowardsMenu) {
+            dismiss(animView, velocity);
+            menuRow.onDismiss();
+        } else {
+            snapClosed(animView, velocity);
+            menuRow.onSnapClosed();
+        }
+    }
+
+    private void handleSwipeFromSnap(MotionEvent ev, View animView, float velocity,
+            NotificationMenuRowPlugin menuRow) {
+        boolean isDismissGesture = isDismissGesture(ev);
+
+        final boolean withinSnapMenuThreshold =
+                menuRow.isWithinSnapMenuThreshold();
+
+        if (withinSnapMenuThreshold && !isDismissGesture) {
+            // Haven't moved enough to unsnap from the menu
+            menuRow.onSnapOpen();
+            snapOpen(animView, menuRow.getMenuSnapTarget(), velocity);
+        } else if (isDismissGesture && !menuRow.shouldSnapBack()) {
+            // Only dismiss if we're not moving towards the menu
+            dismiss(animView, velocity);
+            menuRow.onDismiss();
+        } else {
+            snapClosed(animView, velocity);
+            menuRow.onSnapClosed();
+        }
+    }
+
+    @Override
+    public void dismissChild(final View view, float velocity,
+            boolean useAccelerateInterpolator) {
+        superDismissChild(view, velocity, useAccelerateInterpolator);
+        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.
+            mCallback.handleChildViewDismissed(view);
+        }
+        mCallback.onDismiss();
+        handleMenuCoveredOrDismissed();
+    }
+
+    @VisibleForTesting
+    protected void superDismissChild(final View view, float velocity, boolean useAccelerateInterpolator) {
+        super.dismissChild(view, velocity, useAccelerateInterpolator);
+    }
+
+    @VisibleForTesting
+    protected void superSnapChild(final View animView, final float targetLeft, float velocity) {
+        super.snapChild(animView, targetLeft, velocity);
+    }
+
+    @Override
+    public void snapChild(final View animView, final float targetLeft, float velocity) {
+        superSnapChild(animView, targetLeft, velocity);
+        mCallback.onDragCancelled(animView);
+        if (targetLeft == 0) {
+            handleMenuCoveredOrDismissed();
+        }
+    }
+
+    @Override
+    public void snooze(StatusBarNotification sbn, SnoozeOption snoozeOption) {
+        mCallback.onSnooze(sbn, snoozeOption);
+    }
+
+    @VisibleForTesting
+    protected void handleMenuCoveredOrDismissed() {
+        View exposedMenuView = getExposedMenuView();
+        if (exposedMenuView != null && exposedMenuView == mTranslatingParentView) {
+            clearExposedMenuView();
+        }
+    }
+
+    @VisibleForTesting
+    protected Animator superGetViewTranslationAnimator(View v, float target,
+            ValueAnimator.AnimatorUpdateListener listener) {
+        return super.getViewTranslationAnimator(v, target, listener);
+    }
+
+    @Override
+    public Animator getViewTranslationAnimator(View v, float target,
+            ValueAnimator.AnimatorUpdateListener listener) {
+        if (v instanceof ExpandableNotificationRow) {
+            return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener);
+        } else {
+            return superGetViewTranslationAnimator(v, target, listener);
+        }
+    }
+
+    @Override
+    public void setTranslation(View v, float translate) {
+        if (v instanceof ExpandableNotificationRow) {
+            ((ExpandableNotificationRow) v).setTranslation(translate);
+        } else {
+            Log.wtf(TAG, "setTranslation should only be called on an ExpandableNotificationRow.");
+        }
+    }
+
+    @Override
+    public float getTranslation(View v) {
+        if (v instanceof ExpandableNotificationRow) {
+            return ((ExpandableNotificationRow) v).getTranslation();
+        }
+        else {
+            Log.wtf(TAG, "getTranslation should only be called on an ExpandableNotificationRow.");
+            return 0f;
+        }
+    }
+
+    @Override
+    public boolean swipedFastEnough(float translation, float viewSize) {
+        return swipedFastEnough();
+    }
+
+    @Override
+    @VisibleForTesting
+    protected boolean swipedFastEnough() {
+        return super.swipedFastEnough();
+    }
+
+    @Override
+    public boolean swipedFarEnough(float translation, float viewSize) {
+        return swipedFarEnough();
+    }
+
+    @Override
+    @VisibleForTesting
+    protected boolean swipedFarEnough() {
+        return super.swipedFarEnough();
+    }
+
+    @Override
+    public void dismiss(View animView, float velocity) {
+        dismissChild(animView, velocity,
+                !swipedFastEnough() /* useAccelerateInterpolator */);
+    }
+
+    @Override
+    public void snapOpen(View animView, int targetLeft, float velocity) {
+        snapChild(animView, targetLeft, velocity);
+    }
+
+    @VisibleForTesting
+    protected void snapClosed(View animView, float velocity) {
+        snapChild(animView, 0, velocity);
+    }
+
+    @Override
+    @VisibleForTesting
+    protected float getEscapeVelocity() {
+        return super.getEscapeVelocity();
+    }
+
+    @Override
+    public float getMinDismissVelocity() {
+        return getEscapeVelocity();
+    }
+
+    public void onMenuShown(View animView) {
+        setExposedMenuView(getTranslatingParentView());
+        mCallback.onDragCancelled(animView);
+        Handler handler = getHandler();
+
+        // If we're on the lockscreen we want to false this.
+        if (mCallback.isAntiFalsingNeeded()) {
+            handler.removeCallbacks(getFalsingCheck());
+            handler.postDelayed(getFalsingCheck(), COVER_MENU_DELAY);
+        }
+    }
+
+    @VisibleForTesting
+    protected boolean shouldResetMenu(boolean force) {
+        if (mMenuExposedView == null
+                || (!force && mMenuExposedView == mTranslatingParentView)) {
+            // If no menu is showing or it's showing for this view we do nothing.
+            return false;
+        }
+        return true;
+    }
+
+    public void resetExposedMenuView(boolean animate, boolean force) {
+        if (!shouldResetMenu(force)) {
+            return;
+        }
+        final View prevMenuExposedView = getExposedMenuView();
+        if (animate) {
+            Animator anim = getViewTranslationAnimator(prevMenuExposedView,
+                    0 /* leftTarget */, null /* updateListener */);
+            if (anim != null) {
+                anim.start();
+            }
+        } else if (prevMenuExposedView instanceof ExpandableNotificationRow) {
+            ExpandableNotificationRow row = (ExpandableNotificationRow) prevMenuExposedView;
+            if (!row.isRemoved()) {
+                row.resetTranslation();
+            }
+        }
+        clearExposedMenuView();
+    }
+
+    public static boolean isTouchInView(MotionEvent ev, View view) {
+        if (view == null) {
+            return false;
+        }
+        final int height = (view instanceof ExpandableView)
+                ? ((ExpandableView) view).getActualHeight()
+                : view.getHeight();
+        final int rx = (int) ev.getRawX();
+        final int ry = (int) ev.getRawY();
+        int[] temp = new int[2];
+        view.getLocationOnScreen(temp);
+        final int x = temp[0];
+        final int y = temp[1];
+        Rect rect = new Rect(x, y, x + view.getWidth(), y + height);
+        boolean ret = rect.contains(rx, ry);
+        return ret;
+    }
+
+    public interface NotificationCallback extends SwipeHelper.Callback{
+        boolean isExpanded();
+
+        void handleChildViewDismissed(View view);
+
+        void onSnooze(StatusBarNotification sbn, SnoozeOption snoozeOption);
+
+        void onDismiss();
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
new file mode 100644
index 0000000..c7ab27b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
@@ -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
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.DrawableRes;
+import android.annotation.IdRes;
+import android.content.Context;
+import android.view.View;
+import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.statusbar.policy.KeyButtonView;
+
+/**
+ * Simple contextual button that is added to the {@link ContextualButtonGroup}. Extend if need extra
+ * functionality.
+ */
+public class ContextualButton extends ButtonDispatcher {
+
+    protected final @DrawableRes int mIconResId;
+
+    /**
+      * Create a contextual button that will use a {@link KeyButtonView} and
+      * {@link KeyButtonDrawable} get and show the button from xml to its icon drawable.
+      * @param buttonResId the button view from xml layout
+      * @param iconResId icon resource to be used
+      */
+    public ContextualButton(@IdRes int buttonResId, @DrawableRes int iconResId) {
+        super(buttonResId);
+        mIconResId = iconResId;
+    }
+
+    /**
+     * Reload the drawable from resource id, should reapply the previous dark intensity.
+     */
+    public void updateIcon() {
+        final KeyButtonDrawable currentDrawable = getImageDrawable();
+        KeyButtonDrawable drawable = getNewDrawable();
+        if (currentDrawable != null) {
+            drawable.setDarkIntensity(currentDrawable.getDarkIntensity());
+        }
+        setImageDrawable(drawable);
+    }
+
+    @Override
+    public void setVisibility(int visibility) {
+        super.setVisibility(visibility);
+
+        // Stop any active animations if hidden
+        final KeyButtonDrawable currentDrawable = getImageDrawable();
+        if (visibility != View.VISIBLE && currentDrawable != null && currentDrawable.canAnimate()) {
+            currentDrawable.clearAnimationCallbacks();
+            currentDrawable.resetAnimation();
+        }
+    }
+
+    protected KeyButtonDrawable getNewDrawable() {
+        return KeyButtonDrawable.create(getContext().getApplicationContext(), mIconResId,
+                false /* shadow */);
+    }
+
+    /**
+     * This context is from the view that could be stale after rotation or config change. To get
+     * correct resources use getApplicationContext() as well.
+     * @return current view context
+     */
+    protected Context getContext() {
+        return getCurrentView().getContext();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
new file mode 100644
index 0000000..1b03966
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.view.View;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ContextualButtonGroup extends ButtonDispatcher {
+    private static final int INVALID_INDEX = -1;
+
+    // List of pairs that contains the button and if the button was visible within this group
+    private final List<ButtonData> mButtonData = new ArrayList<>();
+
+    public ContextualButtonGroup(@IdRes int containerId) {
+        super(containerId);
+    }
+
+    /**
+     * Add a contextual button to the group. The order of adding increases in its priority. The
+     * priority is used to determine which button should be visible when setting multiple button's
+     * visibility {@see setButtonVisiblity}.
+     * @param button the button added to the group
+     */
+    public void addButton(@NonNull ContextualButton button) {
+        mButtonData.add(new ButtonData(button));
+    }
+
+    public ContextualButton getContextButton(@IdRes int buttonResId) {
+        int index = getContextButtonIndex(buttonResId);
+        if (index != INVALID_INDEX) {
+            return mButtonData.get(index).button;
+        }
+        return null;
+    }
+
+    public ContextualButton getVisibleContextButton() {
+        for (int i = mButtonData.size() - 1; i >= 0; --i) {
+            if (mButtonData.get(i).markedVisible) {
+                return mButtonData.get(i).button;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set the visibility of the button by {@param buttonResId} with {@param visible}. Only one
+     * button is shown at a time. The input button will only show up if it has higher priority than
+     * a previous button, otherwise it will be marked as visible and shown later if all higher
+     * priority buttons are invisible. Therefore hiding a button will show the next marked visible
+     * button. This group's view will be visible if at least one button is visible.
+     * @return if the button is visible after operation
+     * @throws RuntimeException if the input id does not match any of the ids in the group
+     */
+    public int setButtonVisiblity(@IdRes int buttonResId, boolean visible) {
+        final int index = getContextButtonIndex(buttonResId);
+        if (index == INVALID_INDEX) {
+            throw new RuntimeException("Cannot find the button id of " + buttonResId
+                    + " in context group");
+        }
+        setVisibility(View.INVISIBLE);
+        mButtonData.get(index).markedVisible = visible;
+
+        // Make all buttons invisible except the first markedVisible button
+        boolean alreadyFoundVisibleButton = false;
+        int i = mButtonData.size() - 1;
+        for (; i >= 0; --i) {
+            final ButtonData buttonData = mButtonData.get(i);
+            if (!alreadyFoundVisibleButton && buttonData.markedVisible) {
+                buttonData.setVisibility(View.VISIBLE);
+                setVisibility(View.VISIBLE);
+                alreadyFoundVisibleButton = true;
+            } else {
+                buttonData.setVisibility(View.INVISIBLE);
+            }
+        }
+        return mButtonData.get(index).button.getVisibility();
+    }
+
+    /**
+     * See if button is group visible. Group visible determines if a button can be visible when
+     * higher priority buttons go invisible.
+     * @param buttonResId the button to see if it is group visible
+     * @return true if button is group visible
+     */
+    public boolean isButtonVisibleWithinGroup(@IdRes int buttonResId) {
+        final int index = getContextButtonIndex(buttonResId);
+        return index != INVALID_INDEX && mButtonData.get(index).markedVisible;
+    }
+
+    /**
+     * Update all the icons that are attached to this group. This will get all the buttons to update
+     * their icons for their buttons.
+     */
+    public void updateIcons() {
+        for (ButtonData data : mButtonData) {
+            data.button.updateIcon();
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("ContextualButtonGroup {");
+        pw.println("      getVisibleContextButton(): " + getVisibleContextButton());
+        pw.println("      isVisible(): " + isVisible());
+        pw.println("      mButtonData [ ");
+        for (int i = mButtonData.size() - 1; i >= 0; --i) {
+            final ButtonData data = mButtonData.get(i);
+            pw.println("            " + i + ": markedVisible=" + data.markedVisible
+                    + " visible=" + data.button.getVisibility()
+                    + " alpha=" + data.button.getAlpha());
+        }
+        pw.println("      ]");
+        pw.println("    }");
+    }
+
+    private int getContextButtonIndex(@IdRes int buttonResId) {
+        for (int i = 0; i < mButtonData.size(); ++i) {
+            if (mButtonData.get(i).button.getId() == buttonResId) {
+                return i;
+            }
+        }
+        return INVALID_INDEX;
+    }
+
+    private final static class ButtonData {
+        ContextualButton button;
+        boolean markedVisible;
+
+        ButtonData(ContextualButton button) {
+            this.button = button;
+            this.markedVisible = false;
+        }
+
+        void setVisibility(int visiblity) {
+            button.setVisibility(visiblity);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 0d3ba77..25db4f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -63,9 +63,14 @@
             if (!mDozing) {
                 return;
             }
-            mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
-            mHandler.postDelayed(mPulseOutExtended,
-                    mDozeParameters.getPulseVisibleDurationExtended());
+            // All pulses except notifications should time out on their own.  Pulses due to
+            // notifications should instead be managed externally based off the notification's
+            // lifetime.
+            if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION) {
+                mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
+                mHandler.postDelayed(mPulseOutExtended,
+                        mDozeParameters.getPulseVisibleDurationExtended());
+            }
             mFullyPulsing = true;
         }
 
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 4a05989..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;
@@ -177,7 +179,7 @@
             mReleaseOnExpandFinish = false;
         } else {
             for (NotificationData.Entry entry : mEntriesToRemoveAfterExpand) {
-                if (contains(entry.key)) {
+                if (isAlerting(entry.key)) {
                     // Maybe the heads-up was removed already
                     removeAlertEntry(entry.key);
                 }
@@ -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
@@ -345,7 +346,7 @@
     public void onReorderingAllowed() {
         mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false);
         for (NotificationData.Entry entry : mEntriesToRemoveWhenReorderingAllowed) {
-            if (contains(entry.key)) {
+            if (isAlerting(entry.key)) {
                 // Maybe the heads-up was removed already
                 removeAlertEntry(entry.key);
             }
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 d89bcda..538a260 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -19,6 +19,7 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
+import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
@@ -28,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;
@@ -40,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;
@@ -53,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;
@@ -67,16 +67,14 @@
 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;
@@ -171,7 +169,6 @@
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private boolean mDozing;
     private int mIndicationBottomMargin;
-    private int mIndicationBottomMarginAmbient;
     private float mDarkAmount;
     private int mBurnInXOffset;
     private int mBurnInYOffset;
@@ -246,10 +243,8 @@
         mIndicationText = findViewById(R.id.keyguard_indication_text);
         mIndicationBottomMargin = getResources().getDimensionPixelSize(
                 R.dimen.keyguard_indication_margin_bottom);
-        mIndicationBottomMarginAmbient = getResources().getDimensionPixelSize(
-                R.dimen.keyguard_indication_margin_bottom_ambient);
         mBurnInYOffset = getResources().getDimensionPixelSize(
-                R.dimen.charging_indication_burn_in_prevention_offset_y);
+                R.dimen.default_burn_in_prevention_offset);
         updateCameraVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
         mUnlockMethodCache.addListener(this);
@@ -320,10 +315,8 @@
         super.onConfigurationChanged(newConfig);
         mIndicationBottomMargin = getResources().getDimensionPixelSize(
                 R.dimen.keyguard_indication_margin_bottom);
-        mIndicationBottomMarginAmbient = getResources().getDimensionPixelSize(
-                R.dimen.keyguard_indication_margin_bottom_ambient);
         mBurnInYOffset = getResources().getDimensionPixelSize(
-                R.dimen.charging_indication_burn_in_prevention_offset_y);
+                R.dimen.default_burn_in_prevention_offset);
         MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams();
         if (mlp.bottomMargin != mIndicationBottomMargin) {
             mlp.bottomMargin = mIndicationBottomMargin;
@@ -567,9 +560,7 @@
             return;
         }
         mDarkAmount = darkAmount;
-        mIndicationArea.setAlpha(MathUtils.lerp(1f, 0.7f, darkAmount));
-        mIndicationArea.setTranslationY(MathUtils.lerp(0,
-                mIndicationBottomMargin - mIndicationBottomMarginAmbient, darkAmount));
+        mIndicationArea.setAlpha(1f - darkAmount);
     }
 
     private static boolean isSuccessfulLaunch(int result) {
@@ -711,8 +702,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);
         }
@@ -829,10 +818,8 @@
         updateLeftAffordanceIcon();
 
         if (dozing) {
-            mLockIcon.setVisibility(INVISIBLE);
             mOverlayContainer.setVisibility(INVISIBLE);
         } else {
-            mLockIcon.setVisibility(VISIBLE);
             mOverlayContainer.setVisibility(VISIBLE);
             if (animate) {
                 startFinishDozeAnimation();
@@ -842,10 +829,10 @@
 
     public void dozeTimeTick() {
         if (mDarkAmount == 1) {
-            // Move indication every minute to avoid burn-in
-            int dozeTranslation = mIndicationBottomMargin - mIndicationBottomMarginAmbient;
-            int burnInYOffset = (int) (-mBurnInYOffset + Math.random() * mBurnInYOffset * 2);
-            mIndicationArea.setTranslationY(dozeTranslation + burnInYOffset);
+            // Move views every minute to avoid burn-in
+            int burnInYOffset = getBurnInOffset(mBurnInYOffset * 2, false /* xAxis */)
+                    - mBurnInYOffset;
+            mLockIcon.setTranslationY(burnInYOffset);
         }
     }
 
@@ -854,7 +841,7 @@
             return;
         }
         mBurnInXOffset = burnInXOffset;
-        mIndicationArea.setTranslationX(burnInXOffset);
+        mLockIcon.setTranslationX(burnInXOffset);
     }
 
     private class DefaultLeftButton implements IntentButton {
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 042e4ff..33bc164 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate;
 
 import android.content.res.Resources;
@@ -30,10 +31,6 @@
  */
 public class KeyguardClockPositionAlgorithm {
 
-    private static final long MILLIS_PER_MINUTES = 1000 * 60;
-    private static final float BURN_IN_PREVENTION_PERIOD_Y = 521;
-    private static final float BURN_IN_PREVENTION_PERIOD_X = 83;
-
     /**
      * How much the clock height influences the shade position.
      * 0 means nothing, 1 means move the shade up by the height of the clock
@@ -228,34 +225,15 @@
     }
 
     private float burnInPreventionOffsetY() {
-        return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
-                mBurnInPreventionOffsetY * 2,
-                BURN_IN_PREVENTION_PERIOD_Y)
+        return getBurnInOffset(mBurnInPreventionOffsetY * 2, false /* xAxis */)
                 - mBurnInPreventionOffsetY;
     }
 
     private float burnInPreventionOffsetX() {
-        return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
-                mBurnInPreventionOffsetX * 2,
-                BURN_IN_PREVENTION_PERIOD_X)
+        return getBurnInOffset(mBurnInPreventionOffsetX * 2, true /* xAxis */)
                 - mBurnInPreventionOffsetX;
     }
 
-    /**
-     * Implements a continuous, piecewise linear, periodic zig-zag function
-     *
-     * Can be thought of as a linear approximation of abs(sin(x)))
-     *
-     * @param period period of the function, ie. zigzag(x + period) == zigzag(x)
-     * @param amplitude maximum value of the function
-     * @return a value between 0 and amplitude
-     */
-    private float zigzag(float x, float amplitude, float period) {
-        float xprime = (x % period) / (period / 2);
-        float interpolationAmount = (xprime <= 1) ? xprime : (2 - xprime);
-        return interpolate(0, amplitude, interpolationAmount);
-    }
-
     public static class Result {
 
         /**
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 5630da6..7c84df9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 
 import android.annotation.ColorInt;
 import android.content.Context;
@@ -70,16 +71,18 @@
     private static final int LAYOUT_CUTOUT = 1;
     private static final int LAYOUT_NO_CUTOUT = 2;
 
+    private final Rect mEmptyRect = new Rect(0, 0, 0, 0);
+
     private boolean mShowPercentAvailable;
     private boolean mBatteryCharging;
     private boolean mKeyguardUserSwitcherShowing;
     private boolean mBatteryListening;
 
     private TextView mCarrierLabel;
-    private View mSystemIconsSuperContainer;
     private MultiUserSwitch mMultiUserSwitch;
     private ImageView mMultiUserAvatar;
     private BatteryMeterView mBatteryView;
+    private StatusIconContainer mStatusIconContainer;
 
     private BatteryController mBatteryController;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -99,6 +102,18 @@
      */
     private int mCutoutSideNudge = 0;
 
+    /**
+     * How much to move icons to avoid burn in.
+     */
+    private int mBurnInOffset;
+    private int mCurrentBurnInOffsetX;
+    private int mCurrentBurnInOffsetY;
+
+    /**
+     * Ratio representing being in ambient mode or not.
+     */
+    private float mDarkAmount;
+
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -113,6 +128,7 @@
         mBatteryView = mSystemIconsContainer.findViewById(R.id.battery);
         mCutoutSpace = findViewById(R.id.cutout_space_view);
         mStatusIconArea = findViewById(R.id.status_icon_area);
+        mStatusIconContainer = findViewById(R.id.statusIcons);
 
         loadDimens();
         updateUserSwitcher();
@@ -169,6 +185,8 @@
                 R.dimen.system_icons_super_container_avatarless_margin_end);
         mCutoutSideNudge = getResources().getDimensionPixelSize(
                 R.dimen.display_cutout_margin_consumption);
+        mBurnInOffset = getResources().getDimensionPixelSize(
+                R.dimen.default_burn_in_prevention_offset);
         mShowPercentAvailable = getContext().getResources().getBoolean(
                 com.android.internal.R.bool.config_battery_percentage_setting_available);
     }
@@ -440,6 +458,14 @@
     }
 
     public void onThemeChanged() {
+        mBatteryView.setColorsFromContext(mContext);
+        updateIconsAndTextColors();
+        // Reload user avatar
+        ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
+                .onDensityOrFontScaleChanged();
+    }
+
+    private void updateIconsAndTextColors() {
         @ColorInt int textColor = Utils.getColorAttrDefaultColor(mContext,
                 R.attr.wallpaperTextColor);
         @ColorInt int iconColor = Utils.getColorStateListDefaultColor(mContext,
@@ -448,14 +474,9 @@
         float intensity = textColor == Color.WHITE ? 0 : 1;
         mCarrierLabel.setTextColor(iconColor);
         mIconManager.setTint(iconColor);
-        mBatteryView.setColorsFromContext(mContext);
-        Rect tintArea = new Rect(0, 0, 0, 0);
 
-        applyDarkness(R.id.battery, tintArea, intensity, iconColor);
-        applyDarkness(R.id.clock, tintArea, intensity, iconColor);
-        // Reload user avatar
-        ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
-                .onDensityOrFontScaleChanged();
+        applyDarkness(R.id.battery, mEmptyRect, intensity * (1f - mDarkAmount), iconColor);
+        applyDarkness(R.id.clock, mEmptyRect, intensity, iconColor);
     }
 
     private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
@@ -475,4 +496,32 @@
             mBatteryView.dump(fd, pw, args);
         }
     }
+
+    public void setDarkAmount(float darkAmount) {
+        mDarkAmount = darkAmount;
+        if (darkAmount == 0) {
+            dozeTimeTick();
+        }
+        updateDozeState();
+    }
+
+    public void dozeTimeTick() {
+        mCurrentBurnInOffsetX = getBurnInOffset(mBurnInOffset, true /* xAxis */);
+        mCurrentBurnInOffsetY = getBurnInOffset(mBurnInOffset, false /* xAxis */);
+        updateDozeState();
+    }
+
+    private void updateDozeState() {
+        float alpha = 1f - mDarkAmount;
+        int visibility = alpha != 0f ? VISIBLE : INVISIBLE;
+        mCarrierLabel.setAlpha(alpha);
+        mCarrierLabel.setVisibility(visibility);
+        mStatusIconContainer.setAlpha(alpha);
+        mStatusIconContainer.setVisibility(visibility);
+
+        mSystemIconsContainer.setTranslationX(-mCurrentBurnInOffsetX * 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..2edc294 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -51,7 +51,6 @@
     private boolean mScreenOn;
     private boolean mLastScreenOn;
     private Drawable mUserAvatarIcon;
-    private TrustDrawable mTrustDrawable;
     private final UnlockMethodCache mUnlockMethodCache;
     private AccessibilityController mAccessibilityController;
     private boolean mHasFingerPrintIcon;
@@ -62,28 +61,10 @@
 
     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 +91,6 @@
         final int density = newConfig.densityDpi;
         if (density != mDensity) {
             mDensity = density;
-            mTrustDrawable.stop();
-            mTrustDrawable = new TrustDrawable(getContext());
-            setBackground(mTrustDrawable);
             update();
         }
     }
@@ -122,18 +100,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 +111,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,20 +129,6 @@
             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);
             if (mHasFaceUnlockIcon) {
                 announceForAccessibility(getContext().getString(
@@ -204,9 +153,6 @@
             mLastScreenOn = mScreenOn;
         }
 
-        // Hide trust circle when fingerprint is running.
-        boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !trustHidden;
-        mTrustDrawable.setTrustManaged(trustManaged);
         updateClickability();
     }
 
@@ -250,27 +196,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;
@@ -319,29 +259,4 @@
             return STATE_LOCKED;
         }
     }
-
-    /**
-     * A wrapper around another Drawable that overrides the intrinsic size.
-     */
-    private static class IntrinsicSizeDrawable extends InsetDrawable {
-
-        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;
-        }
-    }
 }
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 66486ce..6bccf31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -35,6 +35,7 @@
 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;
@@ -88,8 +89,8 @@
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 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;
@@ -194,7 +195,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);
@@ -284,7 +285,7 @@
         mNavigationBarView = (NavigationBarView) view;
 
         mNavigationBarView.setDisabledFlags(mDisabledFlags1);
-        mNavigationBarView.setComponents(mRecents, mDivider, mStatusBar.getPanel());
+        mNavigationBarView.setComponents(mStatusBar.getPanel());
         mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged);
         mNavigationBarView.setOnTouchListener(this::onNavigationTouch);
         if (savedInstanceState != null) {
@@ -463,7 +464,7 @@
                 style = rotationCCW ? R.style.RotateButtonCCWStart0 :
                         R.style.RotateButtonCWStart0;
             }
-            mNavigationBarView.updateRotateSuggestionButtonStyle(style, true);
+            mNavigationBarView.updateRotateSuggestionButtonStyle(style);
         }
 
         if (mNavigationBarWindowState != WINDOW_STATE_SHOWING) {
@@ -640,9 +641,12 @@
     // 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 */,
@@ -946,7 +950,7 @@
     private boolean onLongPressRecents() {
         if (mRecents == null || !ActivityTaskManager.supportsMultiWindow(getContext())
                 || !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()
-                || Recents.getConfiguration().isLowRamDevice
+                || ActivityManager.isLowRamDeviceStatic()
                 // If we are connected to the overview service, then disable the recents button
                 || mOverviewProxyService.getProxy() != null) {
             return false;
@@ -1110,7 +1114,7 @@
         }
     };
 
-    class TaskStackListenerImpl extends SysUiTaskStackChangeListener {
+    class TaskStackListenerImpl extends TaskStackChangeListener {
         // Invalidate any rotation suggestion on task change or activity orientation change
         // Note: all callbacks happen on main thread
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
deleted file mode 100644
index 8c02e1f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ /dev/null
@@ -1,295 +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 static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_TOP;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.RecentsComponent;
-import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
-import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.tuner.TunerService;
-
-/**
- * Class to detect gestures on the navigation bar.
- */
-public class NavigationBarGestureHelper implements TunerService.Tunable, GestureHelper {
-
-    private static final String TAG = "NavBarGestureHelper";
-    private static final String KEY_DOCK_WINDOW_GESTURE = "overview_nav_bar_gesture";
-    /**
-     * When dragging from the navigation bar, we drag in recents.
-     */
-    public static final int DRAG_MODE_NONE = -1;
-
-    /**
-     * When dragging from the navigation bar, we drag in recents.
-     */
-    public static final int DRAG_MODE_RECENTS = 0;
-
-    /**
-     * When dragging from the navigation bar, we drag the divider.
-     */
-    public static final int DRAG_MODE_DIVIDER = 1;
-
-    private RecentsComponent mRecentsComponent;
-    private Divider mDivider;
-    private Context mContext;
-    private NavigationBarView mNavigationBarView;
-    private boolean mIsVertical;
-
-    private final QuickStepController mQuickStepController;
-    private final int mScrollTouchSlop;
-    private final StatusBar mStatusBar;
-    private int mTouchDownX;
-    private int mTouchDownY;
-    private boolean mDownOnRecents;
-    private VelocityTracker mVelocityTracker;
-
-    private boolean mDockWindowEnabled;
-    private boolean mDockWindowTouchSlopExceeded;
-    private int mDragMode;
-
-    public NavigationBarGestureHelper(Context context) {
-        mContext = context;
-        mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
-        Resources r = context.getResources();
-        mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
-        mQuickStepController = new QuickStepController(context);
-        Dependency.get(TunerService.class).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
-    }
-
-    public void destroy() {
-        Dependency.get(TunerService.class).removeTunable(this);
-    }
-
-    public void setComponents(RecentsComponent recentsComponent, Divider divider,
-            NavigationBarView navigationBarView) {
-        mRecentsComponent = recentsComponent;
-        mDivider = divider;
-        mNavigationBarView = navigationBarView;
-        mQuickStepController.setComponents(mNavigationBarView);
-    }
-
-    public void setBarState(boolean isVertical, boolean isRTL) {
-        mIsVertical = isVertical;
-        mQuickStepController.setBarState(isVertical, isRTL);
-    }
-
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (!canHandleGestures()) {
-            return false;
-        }
-        boolean result = mQuickStepController.onInterceptTouchEvent(event);
-        if (mDockWindowEnabled) {
-            result |= interceptDockWindowEvent(event);
-        }
-        return result;
-    }
-
-    public boolean onTouchEvent(MotionEvent event) {
-        if (!canHandleGestures()) {
-            return false;
-        }
-        boolean result = mQuickStepController.onTouchEvent(event);
-        if (mDockWindowEnabled) {
-            result |= handleDockWindowEvent(event);
-        }
-        return result;
-    }
-
-    public void onDraw(Canvas canvas) {
-        mQuickStepController.onDraw(canvas);
-    }
-
-    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        mQuickStepController.onLayout(changed, left, top, right, bottom);
-    }
-
-    public void onDarkIntensityChange(float intensity) {
-        mQuickStepController.onDarkIntensityChange(intensity);
-    }
-
-    public void onNavigationButtonLongPress(View v) {
-        mQuickStepController.onNavigationButtonLongPress(v);
-    }
-
-    private boolean interceptDockWindowEvent(MotionEvent event) {
-        switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                handleDragActionDownEvent(event);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                return handleDragActionMoveEvent(event);
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                handleDragActionUpEvent(event);
-                break;
-        }
-        return false;
-    }
-
-    private boolean handleDockWindowEvent(MotionEvent event) {
-        switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                handleDragActionDownEvent(event);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                handleDragActionMoveEvent(event);
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                handleDragActionUpEvent(event);
-                break;
-        }
-        return true;
-    }
-
-    private void handleDragActionDownEvent(MotionEvent event) {
-        mVelocityTracker = VelocityTracker.obtain();
-        mVelocityTracker.addMovement(event);
-        mDockWindowTouchSlopExceeded = false;
-        mTouchDownX = (int) event.getX();
-        mTouchDownY = (int) event.getY();
-
-        if (mNavigationBarView != null) {
-            View recentsButton = mNavigationBarView.getRecentsButton().getCurrentView();
-            if (recentsButton != null) {
-                mDownOnRecents = mTouchDownX >= recentsButton.getLeft()
-                        && mTouchDownX <= recentsButton.getRight()
-                        && mTouchDownY >= recentsButton.getTop()
-                        && mTouchDownY <= recentsButton.getBottom();
-            } else {
-                mDownOnRecents = false;
-            }
-        }
-    }
-
-    private boolean handleDragActionMoveEvent(MotionEvent event) {
-        mVelocityTracker.addMovement(event);
-        int x = (int) event.getX();
-        int y = (int) event.getY();
-        int xDiff = Math.abs(x - mTouchDownX);
-        int yDiff = Math.abs(y - mTouchDownY);
-        if (mDivider == null || mRecentsComponent == null) {
-            return false;
-        }
-        if (!mDockWindowTouchSlopExceeded) {
-            boolean touchSlopExceeded = !mIsVertical
-                    ? yDiff > mScrollTouchSlop && yDiff > xDiff
-                    : xDiff > mScrollTouchSlop && xDiff > yDiff;
-            if (mDownOnRecents && touchSlopExceeded
-                    && mDivider.getView().getWindowManagerProxy().getDockSide() == DOCKED_INVALID) {
-                Rect initialBounds = null;
-                int dragMode = calculateDragMode();
-                int createMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-                if (dragMode == DRAG_MODE_DIVIDER) {
-                    initialBounds = new Rect();
-                    mDivider.getView().calculateBoundsForPosition(mIsVertical
-                                    ? (int) event.getRawX()
-                                    : (int) event.getRawY(),
-                            mDivider.getView().isHorizontalDivision()
-                                    ? DOCKED_TOP
-                                    : DOCKED_LEFT,
-                            initialBounds);
-                } else if (dragMode == DRAG_MODE_RECENTS && mTouchDownX
-                        < mContext.getResources().getDisplayMetrics().widthPixels / 2) {
-                    createMode = SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
-                }
-                boolean docked = mRecentsComponent.splitPrimaryTask(dragMode, createMode,
-                        initialBounds, MetricsEvent.ACTION_WINDOW_DOCK_SWIPE);
-                if (docked) {
-                    mDragMode = dragMode;
-                    if (mDragMode == DRAG_MODE_DIVIDER) {
-                        mDivider.getView().startDragging(false /* animate */, true /* touching*/);
-                    }
-                    mDockWindowTouchSlopExceeded = true;
-                    return true;
-                }
-            }
-        } else {
-            if (mDragMode == DRAG_MODE_DIVIDER) {
-                int position = !mIsVertical ? (int) event.getRawY() : (int) event.getRawX();
-                SnapTarget snapTarget = mDivider.getView().getSnapAlgorithm()
-                        .calculateSnapTarget(position, 0f /* velocity */, false /* hardDismiss */);
-                mDivider.getView().resizeStack(position, snapTarget.position, snapTarget);
-            } else if (mDragMode == DRAG_MODE_RECENTS) {
-                mRecentsComponent.onDraggingInRecents(event.getRawY());
-            }
-        }
-        return false;
-    }
-
-    private void handleDragActionUpEvent(MotionEvent event) {
-        mVelocityTracker.addMovement(event);
-        mVelocityTracker.computeCurrentVelocity(1000);
-        if (mDockWindowTouchSlopExceeded && mDivider != null && mRecentsComponent != null) {
-            if (mDragMode == DRAG_MODE_DIVIDER) {
-                mDivider.getView().stopDragging(mIsVertical
-                                ? (int) event.getRawX()
-                                : (int) event.getRawY(),
-                        mIsVertical
-                                ? mVelocityTracker.getXVelocity()
-                                : mVelocityTracker.getYVelocity(),
-                        true /* avoidDismissStart */, false /* logMetrics */);
-            } else if (mDragMode == DRAG_MODE_RECENTS) {
-                mRecentsComponent.onDraggingInRecentsEnded(mVelocityTracker.getYVelocity());
-            }
-        }
-        mVelocityTracker.recycle();
-        mVelocityTracker = null;
-    }
-
-    private boolean canHandleGestures() {
-        return !mStatusBar.isKeyguardShowing();
-    }
-
-    private int calculateDragMode() {
-        if (mIsVertical && !mDivider.getView().isHorizontalDivision()) {
-            return DRAG_MODE_DIVIDER;
-        }
-        if (!mIsVertical && mDivider.getView().isHorizontalDivision()) {
-            return DRAG_MODE_DIVIDER;
-        }
-        return DRAG_MODE_RECENTS;
-    }
-
-    @Override
-    public void onTuningChanged(String key, String newValue) {
-        switch (key) {
-            case KEY_DOCK_WINDOW_GESTURE:
-                mDockWindowEnabled = newValue != null && (Integer.parseInt(newValue) != 0);
-                break;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index e6f2c33..52134d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -37,7 +37,7 @@
 import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
 import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
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 9d13ea2..c4efa94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -36,17 +36,13 @@
 import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
-import androidx.annotation.ColorInt;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.MotionEvent;
 import android.view.Surface;
@@ -59,7 +55,6 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.DockedStackExistsListener;
 import com.android.systemui.Interpolators;
@@ -68,12 +63,11 @@
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.phone.NavGesture;
 import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsOnboarding;
-import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.NavigationBarCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -106,10 +100,7 @@
     boolean mVertical;
     private int mCurrentRotation = -1;
 
-    boolean mShowMenu;
-    boolean mShowAccessibilityButton;
     boolean mLongClickableAccessibilityButton;
-    boolean mShowRotateButton;
     int mDisabledFlags = 0;
     int mNavigationIconHints = 0;
 
@@ -125,10 +116,6 @@
     private KeyButtonDrawable mHomeDefaultIcon;
     private KeyButtonDrawable mRecentIcon;
     private KeyButtonDrawable mDockedIcon;
-    private KeyButtonDrawable mImeIcon;
-    private KeyButtonDrawable mMenuIcon;
-    private KeyButtonDrawable mAccessibilityIcon;
-    private KeyButtonDrawable mRotateSuggestionIcon;
 
     private GestureHelper mGestureHelper;
     private final DeadZone mDeadZone;
@@ -151,16 +138,13 @@
     private boolean mDockedStackExists;
 
     private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
+    private final ContextualButtonGroup mContextualButtonGroup;
     private Configuration mConfiguration;
 
     private NavigationBarInflaterView mNavigationInflaterView;
-    private RecentsComponent mRecentsComponent;
-    private Divider mDivider;
     private RecentsOnboarding mRecentsOnboarding;
     private NotificationPanelView mPanelView;
 
-    private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;
-
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
      * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
@@ -279,17 +263,30 @@
                 Context.WINDOW_SERVICE)).getDefaultDisplay();
 
         mVertical = false;
-        mShowMenu = false;
-
-        mShowAccessibilityButton = false;
         mLongClickableAccessibilityButton = false;
 
+        // Set up the context group of buttons
+        mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container);
+        final ContextualButton menuButton = new ContextualButton(R.id.menu,
+                R.drawable.ic_sysbar_menu);
+        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.style.RotateButtonCCWStart90);
+        final ContextualButton accessibilityButton =
+                new ContextualButton(R.id.accessibility_button,
+                        R.drawable.ic_sysbar_accessibility_button);
+        mContextualButtonGroup.addButton(menuButton);
+        mContextualButtonGroup.addButton(imeSwitcherButton);
+        mContextualButtonGroup.addButton(rotateSuggestionButton);
+        mContextualButtonGroup.addButton(accessibilityButton);
+
         mOverviewProxyService = Dependency.get(OverviewProxyService.class);
         mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
 
         mConfiguration = new Configuration();
         mConfiguration.updateFrom(context.getResources().getConfiguration());
-        reloadNavIcons();
 
         mScreenPinningNotify = new ScreenPinningNotify(mContext);
         mBarTransitions = new NavigationBarTransitions(this);
@@ -297,14 +294,11 @@
         mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
         mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
         mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
-        mButtonDispatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
-        mButtonDispatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
-        mButtonDispatchers.put(R.id.accessibility_button,
-                new ButtonDispatcher(R.id.accessibility_button));
-        mButtonDispatchers.put(R.id.rotate_suggestion,
-                new ButtonDispatcher(R.id.rotate_suggestion));
-        mButtonDispatchers.put(R.id.menu_container,
-                new ButtonDispatcher(R.id.menu_container));
+        mButtonDispatchers.put(R.id.menu, menuButton);
+        mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton);
+        mButtonDispatchers.put(R.id.accessibility_button, accessibilityButton);
+        mButtonDispatchers.put(R.id.rotate_suggestion, rotateSuggestionButton);
+        mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
         mDeadZone = new DeadZone(this);
     }
 
@@ -316,14 +310,10 @@
         return mBarTransitions.getLightTransitionsController();
     }
 
-    public void setComponents(RecentsComponent recentsComponent, Divider divider,
-            NotificationPanelView panel) {
-        mRecentsComponent = recentsComponent;
-        mDivider = divider;
+    public void setComponents(NotificationPanelView panel) {
         mPanelView = panel;
-        if (mGestureHelper instanceof NavigationBarGestureHelper) {
-            ((NavigationBarGestureHelper) mGestureHelper).setComponents(
-                    recentsComponent, divider, this);
+        if (mGestureHelper instanceof QuickStepController) {
+            ((QuickStepController) mGestureHelper).setComponents(this);
         }
     }
 
@@ -432,10 +422,6 @@
         return mButtonDispatchers.get(R.id.rotate_suggestion);
     }
 
-    public ButtonDispatcher getMenuContainer() {
-        return mButtonDispatchers.get(R.id.menu_container);
-    }
-
     public SparseArray<ButtonDispatcher> getButtonDispatchers() {
         return mButtonDispatchers;
     }
@@ -473,14 +459,7 @@
         }
         if (densityChange || dirChange) {
             mRecentIcon = getDrawable(R.drawable.ic_sysbar_recent);
-            mMenuIcon = getDrawable(R.drawable.ic_sysbar_menu);
-
-            mAccessibilityIcon = getDrawable(R.drawable.ic_sysbar_accessibility_button,
-                    false /* hasShadow */);
-
-            mImeIcon = getDrawable(R.drawable.ic_ime_switcher_default, false /* hasShadow */);
-
-            updateRotateSuggestionButtonStyle(mRotateBtnStyle, false);
+            mContextualButtonGroup.updateIcons();
         }
         if (orientationChange || densityChange || dirChange) {
             mBackIcon = getBackDrawable();
@@ -538,19 +517,11 @@
     }
 
     private KeyButtonDrawable getDrawable(@DrawableRes int icon) {
-        return getDrawable(mContext, icon, true /* hasShadow */);
+        return KeyButtonDrawable.create(mContext, icon, true /* hasShadow */);
     }
 
     private KeyButtonDrawable getDrawable(@DrawableRes int icon, boolean hasShadow) {
-        return getDrawable(mContext, icon, hasShadow);
-    }
-
-    private KeyButtonDrawable getDrawable(Context ctx, @DrawableRes int icon, boolean hasShadow) {
-        final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
-        final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
-        Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
-        Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
-        return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow);
+        return KeyButtonDrawable.create(mContext, icon, hasShadow);
     }
 
     @Override
@@ -609,33 +580,21 @@
         updateRecentsIcon();
 
         // Update IME button visibility, a11y and rotate button always overrides the appearance
-        final boolean showImeButton =
-                !mShowAccessibilityButton &&
-                        !mShowRotateButton &&
-                        ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0);
-        getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE);
-        getImeSwitchButton().setImageDrawable(mImeIcon);
-        updateContextualContainerVisibility();
-
-        // Update menu button, visibility logic in method
-        setMenuVisibility(mShowMenu, true);
-        getMenuButton().setImageDrawable(mMenuIcon);
-
-        // Update rotate button, visibility altered by a11y button logic
-        getRotateSuggestionButton().setImageDrawable(mRotateSuggestionIcon);
-
-        // Update a11y button, visibility logic in state method
-        setAccessibilityButtonState(mShowAccessibilityButton, mLongClickableAccessibilityButton);
-        getAccessibilityButton().setImageDrawable(mAccessibilityIcon);
+        mContextualButtonGroup.setButtonVisiblity(R.id.ime_switcher,
+                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0);
 
         mBarTransitions.reapplyDarkIntensity();
 
         boolean disableHome = ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
 
+        // TODO(b/113914868): investigation log for disappearing home button
+        Log.i(TAG, "updateNavButtonIcons (b/113914868): home disabled=" + disableHome
+                + " mDisabledFlags=" + mDisabledFlags);
+
         // Always disable recents when alternate car mode UI is active.
         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
@@ -782,88 +741,28 @@
     }
 
     public void setMenuVisibility(final boolean show) {
-        setMenuVisibility(show, false);
+        mContextualButtonGroup.setButtonVisiblity(R.id.menu, show);
     }
 
-    public void setMenuVisibility(final boolean show, final boolean force) {
-        if (!force && mShowMenu == show) return;
-
-        mShowMenu = show;
-
-        // Only show Menu if IME switcher, rotate and Accessibility buttons are not shown.
-        final boolean shouldShow = mShowMenu &&
-                !mShowAccessibilityButton &&
-                !mShowRotateButton &&
-                ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
-
-        getMenuButton().setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
-        updateContextualContainerVisibility();
+    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) {
-        mShowAccessibilityButton = visible;
         mLongClickableAccessibilityButton = longClickable;
-        if (visible) {
-            // Accessibility button overrides Menu, IME switcher and rotate buttons.
-            setMenuVisibility(false, true);
-            getImeSwitchButton().setVisibility(View.INVISIBLE);
-            setRotateButtonVisibility(false);
-        }
-
-        getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
         getAccessibilityButton().setLongClickable(longClickable);
-        updateContextualContainerVisibility();
-    }
-
-    public void updateRotateSuggestionButtonStyle(@StyleRes int style, boolean setIcon) {
-        mRotateBtnStyle = style;
-        final Context ctx = getContext();
-
-        // Use the supplied style to set the icon's rotation parameters
-        Context rotateContext = new ContextThemeWrapper(ctx, style);
-
-        // Recreate the icon and set it if needed
-        float previousIntensity = mRotateSuggestionIcon != null
-                ? mRotateSuggestionIcon.getDarkIntensity() : 0;
-        mRotateSuggestionIcon = getDrawable(rotateContext, R.drawable.ic_sysbar_rotate_button,
-                false /* hasShadow */);
-        mRotateSuggestionIcon.setDarkIntensity(previousIntensity);
-
-        if (setIcon) getRotateSuggestionButton().setImageDrawable(mRotateSuggestionIcon);
+        mContextualButtonGroup.setButtonVisiblity(R.id.accessibility_button, visible);
     }
 
     public int setRotateButtonVisibility(boolean visible) {
-        // Never show if a11y is visible
-        final boolean adjVisible = visible && !mShowAccessibilityButton;
-        final int vis = adjVisible ? View.VISIBLE : View.INVISIBLE;
-
-        // No need to do anything if the request matches the current state
-        if (vis == getRotateSuggestionButton().getVisibility()) return vis;
-
-        getRotateSuggestionButton().setVisibility(vis);
-        mShowRotateButton = visible;
-        updateContextualContainerVisibility();
-
-        // Stop any active animations if hidden
-        if (!visible && mRotateSuggestionIcon.canAnimate()) {
-            mRotateSuggestionIcon.clearAnimationCallbacks();
-            mRotateSuggestionIcon.resetAnimation();
-        }
-
-        // Hide/restore other button visibility, if necessary
-        updateNavButtonIcons();
-
-        // Return applied visibility
-        return vis;
+        return mContextualButtonGroup.setButtonVisiblity(R.id.rotate_suggestion, visible);
     }
 
-    public boolean isRotateButtonVisible() { return mShowRotateButton; }
-
-    private void updateContextualContainerVisibility() {
-        // Only show the menu container when one of its buttons are visible
-        getMenuContainer().setVisibility((mShowAccessibilityButton || mShowRotateButton || mShowMenu
-                || (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0)
-                ? VISIBLE : INVISIBLE);
+    public boolean isRotateButtonVisible() {
+        return getRotateSuggestionButton().isVisible();
     }
 
     void hideRecentsOnboarding() {
@@ -897,6 +796,7 @@
 
         DockedStackExistsListener.register(mDockedListener);
         updateRotatedViews();
+        reloadNavIcons();
     }
 
     public void onDarkIntensityChange(float intensity) {
@@ -998,7 +898,6 @@
 
         // force the low profile & disabled states into compliance
         mBarTransitions.init();
-        setMenuVisibility(mShowMenu, true /* force */);
 
         if (DEBUG) {
             Log.d(TAG, "reorient(): rot=" + mCurrentRotation);
@@ -1170,8 +1069,8 @@
 
     @Override
     public void onPluginDisconnected(NavGesture plugin) {
-        NavigationBarGestureHelper defaultHelper = new NavigationBarGestureHelper(getContext());
-        defaultHelper.setComponents(mRecentsComponent, mDivider, this);
+        QuickStepController defaultHelper = new QuickStepController(getContext());
+        defaultHelper.setComponents(this);
         if (mGestureHelper != null) {
             mGestureHelper.destroy();
         }
@@ -1204,17 +1103,20 @@
         pw.println(String.format("      disabled=0x%08x vertical=%s menu=%s",
                         mDisabledFlags,
                         mVertical ? "true" : "false",
-                        mShowMenu ? "true" : "false"));
+                        getMenuButton().isVisible() ? "true" : "false"));
 
         dumpButton(pw, "back", getBackButton());
         dumpButton(pw, "home", getHomeButton());
         dumpButton(pw, "rcnt", getRecentsButton());
         dumpButton(pw, "menu", getMenuButton());
+        dumpButton(pw, "rota", getRotateSuggestionButton());
         dumpButton(pw, "a11y", getAccessibilityButton());
 
-        mRecentsOnboarding.dump(pw);
-
         pw.println("    }");
+
+        mContextualButtonGroup.dump(pw);
+        mGestureHelper.dump(pw);
+        mRecentsOnboarding.dump(pw);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
index 09833d4..1524f80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
@@ -95,6 +95,9 @@
     }
 
     private View findNearestChild(MotionEvent event) {
+        if (mClickableChildren.isEmpty()) {
+            return null;
+        }
         return mClickableChildren
                 .stream()
                 .filter(v -> v.isAttachedToWindow())
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 6b6566c..c08366a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.NonNull;
 import android.app.Notification;
 import android.os.SystemClock;
 import android.service.notification.StatusBarNotification;
@@ -23,6 +24,9 @@
 import android.util.Log;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.statusbar.AlertingNotificationManager;
+import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -43,15 +47,18 @@
 /**
  * A class to handle notifications and their corresponding groups.
  */
-public class NotificationGroupManager implements OnHeadsUpChangedListener {
+public class NotificationGroupManager implements OnHeadsUpChangedListener,
+        OnAmbientChangedListener {
 
     private static final String TAG = "NotificationGroupManager";
-    private static final long HEADS_UP_TRANSFER_TIMEOUT = 300;
+    private static final long ALERT_TRANSFER_TIMEOUT = 300;
     private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
     private OnGroupChangeListener mListener;
     private int mBarState = -1;
     private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
     private HeadsUpManager mHeadsUpManager;
+    private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
+    private boolean mIsDozing;
     private boolean mIsUpdatingUnchangedGroup;
     private HashMap<String, NotificationData.Entry> mPendingNotifications;
 
@@ -162,40 +169,58 @@
                 mListener.onGroupCreatedFromChildren(group);
             }
         }
-        cleanUpHeadsUpStatesOnAdd(group, false /* addIsPending */);
+        cleanUpAlertStatesOnAdd(group, false /* addIsPending */);
     }
 
     public void onPendingEntryAdded(NotificationData.Entry shadeEntry) {
         String groupKey = getGroupKey(shadeEntry.notification);
         NotificationGroup group = mGroupMap.get(groupKey);
         if (group != null) {
-            cleanUpHeadsUpStatesOnAdd(group, true /* addIsPending */);
+            cleanUpAlertStatesOnAdd(group, true /* addIsPending */);
         }
     }
 
     /**
-     * Clean up the heads up states when a new child was added.
+     * Set whether or not the device is dozing.  This allows the group manager to reset some
+     * specific alert state logic based off when the state changes.
+     * @param isDozing if the device is dozing.
+     */
+    public void setDozing(boolean isDozing) {
+        if (mIsDozing != isDozing) {
+            for (NotificationGroup group : mGroupMap.values()) {
+                group.lastAlertTransfer = 0;
+                group.alertSummaryOnNextAddition = false;
+            }
+        }
+        mIsDozing = isDozing;
+    }
+
+    /**
+     * Clean up the alert states when a new child was added.
      * @param group The group where a view was added or will be added.
      * @param addIsPending True if is the addition still pending or false has it already been added.
      */
-    private void cleanUpHeadsUpStatesOnAdd(NotificationGroup group, boolean addIsPending) {
-        if (!addIsPending && group.hunSummaryOnNextAddition) {
-            if (!mHeadsUpManager.contains(group.summary.key)) {
-                mHeadsUpManager.showNotification(group.summary);
+    private void cleanUpAlertStatesOnAdd(NotificationGroup group, boolean addIsPending) {
+
+        AlertingNotificationManager alertManager =
+                mIsDozing ? mAmbientPulseManager : mHeadsUpManager;
+        if (!addIsPending && group.alertSummaryOnNextAddition) {
+            if (!alertManager.isAlerting(group.summary.key)) {
+                alertManager.showNotification(group.summary);
             }
-            group.hunSummaryOnNextAddition = false;
+            group.alertSummaryOnNextAddition = false;
         }
         // Because notification groups are not delivered as a whole unit, it may happen that a
         // group child gets added quite a bit after the summary got posted. Our guidance is, that
         // apps should always post the group summary as well and we'll hide it for them if the child
-        // is the only child in a group. Because of this, we also have to transfer heads up to the
-        // child, otherwise the invisible summary would be heads-upped.
+        // is the only child in a group. Because of this, we also have to transfer alert to the
+        // child, otherwise the invisible summary would be alerted.
         // This transfer to the child is not always correct in case the app has just posted another
         // child in addition to the existing one, but it hasn't arrived in systemUI yet. In such
-        // a scenario we would transfer the heads up to the old child and the wrong notification
-        // would be heads-upped. In oder to avoid this, we'll recover from this issue and hun the
+        // a scenario we would transfer the alert to the old child and the wrong notification
+        // would be alerted. In order to avoid this, we'll recover from this issue and alert the
         // summary again instead of the old child if it's within a certain timeout.
-        if (SystemClock.elapsedRealtime() - group.lastHeadsUpTransfer < HEADS_UP_TRANSFER_TIMEOUT) {
+        if (SystemClock.elapsedRealtime() - group.lastAlertTransfer < ALERT_TRANSFER_TIMEOUT) {
             if (!onlySummaryAlerts(group.summary)) {
                 return;
             }
@@ -215,26 +240,24 @@
             int size = children.size();
             for (int i = 0; i < size; i++) {
                 NotificationData.Entry entry = children.get(i);
-                if (onlySummaryAlerts(entry) && entry.row.isHeadsUp()) {
+                if (onlySummaryAlerts(entry) && alertManager.isAlerting(entry.key)) {
                     releasedChild = true;
-                    mHeadsUpManager.removeNotification(
-                            entry.key, true /* releaseImmediately */);
+                    alertManager.removeNotification(entry.key, true /* releaseImmediately */);
                 }
             }
             if (isolatedChild != null && onlySummaryAlerts(isolatedChild)
-                    && isolatedChild.row.isHeadsUp()) {
+                    && alertManager.isAlerting(isolatedChild.key)) {
                 releasedChild = true;
-                mHeadsUpManager.removeNotification(
-                        isolatedChild.key, true /* releaseImmediately */);
+                alertManager.removeNotification(isolatedChild.key, true /* releaseImmediately */);
             }
-            if (releasedChild && !mHeadsUpManager.contains(group.summary.key)) {
+            if (releasedChild && !alertManager.isAlerting(group.summary.key)) {
                 boolean notifyImmediately = (numChildren - numPendingChildren) > 1;
                 if (notifyImmediately) {
-                    mHeadsUpManager.showNotification(group.summary);
+                    alertManager.showNotification(group.summary);
                 } else {
-                    group.hunSummaryOnNextAddition = true;
+                    group.alertSummaryOnNextAddition = true;
                 }
-                group.lastHeadsUpTransfer = 0;
+                group.lastAlertTransfer = 0;
             }
         }
     }
@@ -264,8 +287,8 @@
     }
 
     private void onEntryBecomingChild(NotificationData.Entry entry) {
-        if (entry.row.isHeadsUp()) {
-            onHeadsUpStateChanged(entry, true);
+        if (shouldIsolate(entry)) {
+            isolateNotification(entry);
         }
     }
 
@@ -281,7 +304,11 @@
                         && hasIsolatedChildren(group)));
         if (prevSuppressed != group.suppressed) {
             if (group.suppressed) {
-                handleSuppressedSummaryHeadsUpped(group.summary);
+                if (mHeadsUpManager.isAlerting(group.summary.key)) {
+                    handleSuppressedSummaryAlerted(group.summary, mHeadsUpManager);
+                } else if (mAmbientPulseManager.isAlerting(group.summary.key)) {
+                    handleSuppressedSummaryAlerted(group.summary, mAmbientPulseManager);
+                }
             }
             if (!mIsUpdatingUnchangedGroup && mListener != null) {
                 mListener.onGroupsChanged();
@@ -495,54 +522,56 @@
     }
 
     @Override
+    public void onAmbientStateChanged(NotificationData.Entry entry, boolean isAmbient) {
+        onAlertStateChanged(entry, isAmbient, mAmbientPulseManager);
+    }
+
+    @Override
     public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+        onAlertStateChanged(entry, isHeadsUp, mHeadsUpManager);
+    }
+
+    private void onAlertStateChanged(NotificationData.Entry entry, boolean isAlerting,
+            AlertingNotificationManager alertManager) {
         final StatusBarNotification sbn = entry.notification;
-        if (entry.row.isHeadsUp()) {
-            if (shouldIsolate(sbn)) {
-                // We will be isolated now, so lets update the groups
-                onEntryRemovedInternal(entry, entry.notification);
-
-                mIsolatedEntries.put(sbn.getKey(), sbn);
-
-                onEntryAdded(entry);
-                // We also need to update the suppression of the old group, because this call comes
-                // even before the groupManager knows about the notification at all.
-                // When the notification gets added afterwards it is already isolated and therefore
-                // it doesn't lead to an update.
-                updateSuppression(mGroupMap.get(entry.notification.getGroupKey()));
-                mListener.onGroupsChanged();
-            } else {
-                handleSuppressedSummaryHeadsUpped(entry);
+        if (isAlerting) {
+            if (shouldIsolate(entry)) {
+                isolateNotification(entry);
+            } else if (sbn.getNotification().isGroupSummary()
+                    && isGroupSuppressed(sbn.getGroupKey())){
+                handleSuppressedSummaryAlerted(entry, alertManager);
             }
         } else {
-            if (mIsolatedEntries.containsKey(sbn.getKey())) {
-                // not isolated anymore, we need to update the groups
-                onEntryRemovedInternal(entry, entry.notification);
-                mIsolatedEntries.remove(sbn.getKey());
-                onEntryAdded(entry);
-                mListener.onGroupsChanged();
-            }
+            stopIsolatingNotification(entry);
         }
     }
 
-    private void handleSuppressedSummaryHeadsUpped(NotificationData.Entry entry) {
-        StatusBarNotification sbn = entry.notification;
+    /**
+     * Handles the scenario where a summary that has been suppressed is alerted.  A suppressed
+     * summary should for all intents and purposes be invisible to the user and as a result should
+     * not alert.  When this is the case, it is our responsibility to pass the alert to the
+     * appropriate child which will be the representative notification alerting for the group.
+     * @param summary the summary that is suppressed and alerting
+     * @param alertManager the alert manager that manages the alerting summary
+     */
+    private void handleSuppressedSummaryAlerted(@NonNull NotificationData.Entry summary,
+            @NonNull AlertingNotificationManager alertManager) {
+        StatusBarNotification sbn = summary.notification;
         if (!isGroupSuppressed(sbn.getGroupKey())
                 || !sbn.getNotification().isGroupSummary()
-                || !entry.row.isHeadsUp()) {
+                || !alertManager.isAlerting(sbn.getKey())) {
             return;
         }
 
-        // The parent of a suppressed group got huned, lets hun the child!
+        // The parent of a suppressed group got alerted, lets alert the child!
         NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
 
-        if (pendingInflationsWillAddChildren(notificationGroup)) {
-            // New children will actually be added to this group, let's not transfer the heads
-            // up
-            return;
-        }
-
         if (notificationGroup != null) {
+            if (pendingInflationsWillAddChildren(notificationGroup)) {
+                // New children will actually be added to this group, let's not transfer the alert.
+                return;
+            }
+
             Iterator<NotificationData.Entry> iterator
                     = notificationGroup.children.values().iterator();
             NotificationData.Entry child = iterator.hasNext() ? iterator.next() : null;
@@ -551,20 +580,35 @@
             }
             if (child != null) {
                 if (child.row.keepInParent() || child.row.isRemoved() || child.row.isDismissed()) {
-                    // the notification is actually already removed, no need to do heads-up on it.
+                    // the notification is actually already removed, no need to do alert on it.
                     return;
                 }
-                if (mHeadsUpManager.contains(child.key)) {
-                    mHeadsUpManager.updateNotification(child.key, true /* alert */);
-                } else {
-                    if (onlySummaryAlerts(entry)) {
-                        notificationGroup.lastHeadsUpTransfer = SystemClock.elapsedRealtime();
-                    }
-                    mHeadsUpManager.showNotification(child);
-                }
+                transferAlertStateToChild(summary, child, alertManager);
             }
         }
-        mHeadsUpManager.removeNotification(entry.key, true /* releaseImmediately */);
+    }
+
+    /**
+     * Transfers the alert state from a given summary notification to the specified child.  The
+     * result is the child will now alert while the summary does not.
+     *
+     * @param summary the currently alerting summary notification
+     * @param child the child that should receive the alert
+     * @param alertManager the manager for the alert
+     */
+    private void transferAlertStateToChild(@NonNull NotificationData.Entry summary,
+            @NonNull NotificationData.Entry child,
+            @NonNull AlertingNotificationManager alertManager) {
+        NotificationGroup notificationGroup = mGroupMap.get(summary.notification.getGroupKey());
+        if (alertManager.isAlerting(child.key)) {
+            alertManager.updateNotification(child.key, true /* alert */);
+        } else {
+            if (onlySummaryAlerts(summary)) {
+                notificationGroup.lastAlertTransfer = SystemClock.elapsedRealtime();
+            }
+            alertManager.showNotification(child);
+        }
+        alertManager.removeNotification(summary.key, true /* releaseImmediately */);
     }
 
     private boolean onlySummaryAlerts(NotificationData.Entry entry) {
@@ -596,13 +640,69 @@
         return false;
     }
 
-    private boolean shouldIsolate(StatusBarNotification sbn) {
+    /**
+     * Whether a notification that is normally part of a group should be temporarily isolated from
+     * the group and put in their own group visually.  This generally happens when the notification
+     * is alerting.
+     *
+     * @param entry the notification to check
+     * @return true if the entry should be isolated
+     */
+
+    private boolean shouldIsolate(NotificationData.Entry entry) {
+        StatusBarNotification sbn = entry.notification;
         NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
-        return (sbn.isGroup() && !sbn.getNotification().isGroupSummary())
-                && (sbn.getNotification().fullScreenIntent != null
-                        || notificationGroup == null
-                        || !notificationGroup.expanded
-                        || isGroupNotFullyVisible(notificationGroup));
+        if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
+            return false;
+        }
+        if (!mIsDozing && !mHeadsUpManager.isAlerting(entry.key)) {
+            return false;
+        }
+        if (mIsDozing && !mAmbientPulseManager.isAlerting(entry.key)) {
+            return false;
+        }
+        return (sbn.getNotification().fullScreenIntent != null
+                    || notificationGroup == null
+                    || !notificationGroup.expanded
+                    || isGroupNotFullyVisible(notificationGroup));
+    }
+
+    /**
+     * Isolate a notification from its group so that it visually shows as its own group.
+     *
+     * @param entry the notification to isolate
+     */
+    private void isolateNotification(NotificationData.Entry entry) {
+        StatusBarNotification sbn = entry.notification;
+
+        // We will be isolated now, so lets update the groups
+        onEntryRemovedInternal(entry, entry.notification);
+
+        mIsolatedEntries.put(sbn.getKey(), sbn);
+
+        onEntryAdded(entry);
+        // We also need to update the suppression of the old group, because this call comes
+        // even before the groupManager knows about the notification at all.
+        // When the notification gets added afterwards it is already isolated and therefore
+        // it doesn't lead to an update.
+        updateSuppression(mGroupMap.get(entry.notification.getGroupKey()));
+        mListener.onGroupsChanged();
+    }
+
+    /**
+     * Stop isolating a notification and re-group it with its original logical group.
+     *
+     * @param entry the notification to un-isolate
+     */
+    private void stopIsolatingNotification(NotificationData.Entry entry) {
+        StatusBarNotification sbn = entry.notification;
+        if (mIsolatedEntries.containsKey(sbn.getKey())) {
+            // not isolated anymore, we need to update the groups
+            onEntryRemovedInternal(entry, entry.notification);
+            mIsolatedEntries.remove(sbn.getKey());
+            onEntryAdded(entry);
+            mListener.onGroupsChanged();
+        }
     }
 
     private boolean isGroupNotFullyVisible(NotificationGroup notificationGroup) {
@@ -641,11 +741,11 @@
          */
         public boolean suppressed;
         /**
-         * The time when the last heads transfer from group to child happened, while the summary
-         * has the flags to heads up on its own.
+         * The time when the last alert transfer from group to child happened, while the summary
+         * has the flags to alert up on its own.
          */
-        public long lastHeadsUpTransfer;
-        public boolean hunSummaryOnNextAddition;
+        public long lastAlertTransfer;
+        public boolean alertSummaryOnNextAddition;
 
         @Override
         public String toString() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
index 9ff907b..9e561d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
@@ -24,7 +24,7 @@
 import com.android.systemui.plugins.NotificationListenerController;
 import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 
 import java.util.ArrayList;
 
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 e5e5d40..6d53cd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -63,6 +63,7 @@
 import com.android.systemui.fragments.FragmentHostManager;
 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.FlingAnimationUtils;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -123,8 +124,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";
@@ -455,6 +454,10 @@
         initBottomArea();
         setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount);
 
+        if (mKeyguardStatusBar != null) {
+            mKeyguardStatusBar.onThemeChanged();
+        }
+
         setKeyguardStatusViewVisibility(mBarState, false, false);
         setKeyguardBottomAreaVisibility(mBarState, false);
     }
@@ -728,7 +731,11 @@
             mQsExpandImmediate = true;
             mNotificationStackScroller.setShouldShowShelfOnly(true);
         }
-        expand(true /* animate */);
+        if (isFullyCollapsed()){
+            expand(true /* animate */);
+        } else {
+            flingSettings(0 /* velocity */, FLING_EXPAND);
+        }
     }
 
     public void expandWithoutQs() {
@@ -1775,13 +1782,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;
         }
@@ -1836,10 +1839,10 @@
             return;
         }
         float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
-        mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
-                * mKeyguardStatusBarAnimateAlpha);
-        mKeyguardStatusBar.setVisibility(mKeyguardStatusBar.getAlpha() != 0f
-                && !mDozing ? VISIBLE : INVISIBLE);
+        float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
+                * mKeyguardStatusBarAnimateAlpha;
+        mKeyguardStatusBar.setAlpha(newAlpha);
+        mKeyguardStatusBar.setVisibility(newAlpha != 0f ? VISIBLE : INVISIBLE);
     }
 
     private void updateKeyguardBottomAreaAlpha() {
@@ -2347,16 +2350,7 @@
     }
 
     private void updateDozingVisibilities(boolean animate) {
-        if (mDozing) {
-            mKeyguardStatusBar.setVisibility(View.INVISIBLE);
-            mKeyguardBottomArea.setDozing(mDozing, animate);
-        } else {
-            mKeyguardStatusBar.setVisibility(View.VISIBLE);
-            mKeyguardBottomArea.setDozing(mDozing, animate);
-            if (animate) {
-                animateKeyguardStatusBarIn(DOZE_ANIMATION_DURATION);
-            }
-        }
+        mKeyguardBottomArea.setDozing(mDozing, animate);
     }
 
     @Override
@@ -2749,6 +2743,9 @@
                         }
                     });
             mNotificationStackScroller.setQsContainer((ViewGroup) mQs.getView());
+            if (mQs instanceof QSFragment) {
+                mKeyguardStatusBar.setQSPanel(((QSFragment) mQs).getQsPanel());
+            }
             updateQsExpansion();
         }
 
@@ -2811,6 +2808,7 @@
     private void setDarkAmount(float linearAmount, float amount) {
         mInterpolatedDarkAmount = amount;
         mLinearDarkAmount = linearAmount;
+        mKeyguardStatusBar.setDarkAmount(mInterpolatedDarkAmount);
         mKeyguardStatusView.setDarkAmount(mInterpolatedDarkAmount);
         mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount);
         positionClockAndNotifications();
@@ -2837,6 +2835,7 @@
     }
 
     public void dozeTimeTick() {
+        mKeyguardStatusBar.dozeTimeTick();
         mKeyguardStatusView.dozeTimeTick();
         mKeyguardBottomArea.dozeTimeTick();
         if (mInterpolatedDarkAmount > 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index a900c14..553165b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -67,8 +67,8 @@
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
 import com.android.systemui.statusbar.policy.BluetoothController;
@@ -595,16 +595,29 @@
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                 mContext.getString(R.string.instant_apps));
         mCurrentNotifs.add(new Pair<>(pkg, userId));
-        String message = mContext.getString(R.string.instant_apps_message);
+
+        String helpUrl = mContext.getString(R.string.instant_apps_help_url);
+        boolean hasHelpUrl = !helpUrl.isEmpty();
+        String message = mContext.getString(hasHelpUrl
+                ? R.string.instant_apps_message_with_help
+                : R.string.instant_apps_message);
+
         UserHandle user = UserHandle.of(userId);
         PendingIntent appInfoAction = PendingIntent.getActivityAsUser(mContext, 0,
                 new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                         .setData(Uri.fromParts("package", pkg, null)), 0, null, user);
         Action action = new Notification.Action.Builder(null, mContext.getString(R.string.app_info),
                 appInfoAction).build();
+        PendingIntent helpCenterIntent = hasHelpUrl
+                ? PendingIntent.getActivityAsUser(mContext, 0,
+                new Intent(Intent.ACTION_VIEW).setData(Uri.parse(
+                        helpUrl)),
+                0, null, user)
+                : null;
 
         Intent browserIntent = getTaskIntent(taskId, userId);
-        Notification.Builder builder = new Notification.Builder(mContext, NotificationChannels.GENERAL);
+        Notification.Builder builder = new Notification.Builder(mContext,
+                NotificationChannels.GENERAL);
         if (browserIntent != null && browserIntent.isWebIntent()) {
             // Make sure that this doesn't resolve back to an instant app
             browserIntent.setComponent(null)
@@ -632,7 +645,8 @@
 
             PendingIntent webPendingIntent = PendingIntent.getActivityAsUser(mContext, 0,
                     goToWebIntent, 0, null, user);
-            Action webAction = new Notification.Action.Builder(null, mContext.getString(R.string.go_to_web),
+            Action webAction = new Notification.Action.Builder(null,
+                    mContext.getString(R.string.go_to_web),
                     webPendingIntent).build();
             builder.addAction(webAction);
         }
@@ -640,13 +654,15 @@
         noMan.notifyAsUser(pkg, SystemMessage.NOTE_INSTANT_APPS, builder
                         .addExtras(extras)
                         .addAction(action)
-                        .setContentIntent(appInfoAction)
+                        .setContentIntent(helpCenterIntent)
                         .setColor(mContext.getColor(R.color.instant_apps_color))
-                        .setContentTitle(appInfo.loadLabel(mContext.getPackageManager()))
+                        .setContentTitle(mContext.getString(R.string.instant_apps_title,
+                                appInfo.loadLabel(mContext.getPackageManager())))
                         .setLargeIcon(Icon.createWithResource(pkg, appInfo.icon))
                         .setSmallIcon(Icon.createWithResource(mContext.getPackageName(),
                                 R.drawable.instant_icon))
                         .setContentText(message)
+                        .setStyle(new Notification.BigTextStyle().bigText(message))
                         .setOngoing(true)
                         .build(),
                 new UserHandle(userId));
@@ -781,7 +797,7 @@
         mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
     }
 
-    private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
+    private final TaskStackChangeListener mTaskListener = new TaskStackChangeListener() {
         @Override
         public void onTaskStackChanged() {
             // Listen for changes to stacks and then check which instant apps are foreground.
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 30e6afa..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;
@@ -58,10 +58,12 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.system.NavigationBarCompat;
+import java.io.PrintWriter;
 
 /**
  * Class to detect gestures on the navigation bar and implement quick scrub.
@@ -75,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;
@@ -117,18 +120,11 @@
     private final int mTrackEndPadding;
     private final int mHomeBackGestureDragLimit;
     private final Context mContext;
+    private final StatusBar mStatusBar;
     private final Matrix mTransformGlobalMatrix = new Matrix();
     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
@@ -195,6 +191,7 @@
     public QuickStepController(Context context) {
         final Resources res = context.getResources();
         mContext = context;
+        mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
         mOverviewEventSender = Dependency.get(OverviewProxyService.class);
         mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness);
         mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
@@ -207,7 +204,7 @@
     public void setComponents(NavigationBarView navigationBarView) {
         mNavigationBarView = navigationBarView;
 
-        mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton()
+        mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton(mContext)
                 ? View.GONE
                 : View.VISIBLE);
     }
@@ -218,6 +215,10 @@
      */
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
+        if (mStatusBar.isKeyguardShowing()) {
+            // Disallow any handling when the keyguard is showing
+            return false;
+        }
         return handleTouchEvent(event);
     }
 
@@ -227,6 +228,11 @@
      */
     @Override
     public boolean onTouchEvent(MotionEvent event) {
+        if (mStatusBar.isKeyguardShowing()) {
+            // Disallow any handling when the keyguard is showing
+            return false;
+        }
+
         // The same down event was just sent on intercept and therefore can be ignored here
         final boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
                 && mOverviewEventSender.getProxy() != null;
@@ -331,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();
@@ -483,6 +489,21 @@
         mHandler.removeCallbacksAndMessages(null);
     }
 
+    @Override
+    public void dump(PrintWriter pw) {
+        pw.println("QuickStepController {");
+        pw.print("    "); pw.println("mQuickScrubActive=" + mQuickScrubActive);
+        pw.print("    "); pw.println("mQuickStepStarted=" + mQuickStepStarted);
+        pw.print("    "); pw.println("mAllowGestureDetection=" + mAllowGestureDetection);
+        pw.print("    "); pw.println("mBackGestureActive=" + mBackGestureActive);
+        pw.print("    "); pw.println("mCanPerformBack=" + mCanPerformBack);
+        pw.print("    "); pw.println("mNotificationsVisibleOnDown=" + mNotificationsVisibleOnDown);
+        pw.print("    "); pw.println("mIsVertical=" + mIsVertical);
+        pw.print("    "); pw.println("mIsRTL=" + mIsRTL);
+        pw.print("    "); pw.println("mIsInScreenPinning=" + mIsInScreenPinning);
+        pw.println("}");
+    }
+
     private void startQuickStep(MotionEvent event) {
         if (mIsInScreenPinning) {
             mNavigationBarView.showPinningEscapeToast();
@@ -579,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);
                 }
@@ -610,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();
             }
         }
@@ -681,7 +701,8 @@
     }
 
     private boolean canPerformHomeBackGesture() {
-        return swipeHomeGoBackGestureEnabled() && mOverviewEventSender.getBackButtonAlpha() > 0;
+        return swipeHomeGoBackGestureEnabled(mContext)
+                && mOverviewEventSender.getBackButtonAlpha() > 0;
     }
 
     private void performBack() {
@@ -718,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
new file mode 100644
index 0000000..15e189c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.DrawableRes;
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.annotation.StyleRes;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.util.Utils;
+
+public class RotationContextButton extends ContextualButton {
+
+    private @StyleRes int mStyleRes;
+
+    public RotationContextButton(@IdRes int buttonResId, @DrawableRes int iconResId,
+            @StyleRes int style) {
+        super(buttonResId, iconResId);
+        mStyleRes = style;
+    }
+
+    public void setStyle(@StyleRes int styleRes) {
+        mStyleRes = styleRes;
+    }
+
+    @Override
+    public void setVisibility(int visibility) {
+        super.setVisibility(visibility);
+
+        // Start the rotation animation once it becomes visible
+        final KeyButtonDrawable currentDrawable = getImageDrawable();
+        if (visibility == View.VISIBLE && currentDrawable != null) {
+            currentDrawable.resetAnimation();
+            currentDrawable.startAnimation();
+        }
+    }
+
+    @Override
+    protected KeyButtonDrawable getNewDrawable() {
+        Context context = new ContextThemeWrapper(getContext().getApplicationContext(), mStyleRes);
+        return KeyButtonDrawable.create(context, mIconResId, false /* shadow */);
+    }
+}
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 459b4d7..a7c43cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -102,6 +102,8 @@
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.provider.Settings;
+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;
@@ -154,6 +156,7 @@
 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;
@@ -179,14 +182,11 @@
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.ScreenPinningRequest;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
-import com.android.systemui.recents.events.activity.UndockingTaskEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 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;
@@ -254,7 +254,8 @@
         ActivityStarter, OnUnlockMethodChangedListener,
         OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
         ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter,
-        StatusBarStateController.StateListener {
+        StatusBarStateController.StateListener,  AmbientPulseManager.OnAmbientChangedListener,
+        ActivityLaunchAnimator.Callback {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -380,8 +381,6 @@
     // settings
     private QSPanel mQSPanel;
 
-    // top bar
-    private KeyguardStatusBarView mKeyguardStatusBar;
     KeyguardIndicationController mKeyguardIndicationController;
 
     // RemoteInputView to be activated after unlock
@@ -632,9 +631,11 @@
 
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
         mColorExtractor.addOnColorsChangedListener(this);
-        mStatusBarStateController.addListener(this);
+        mStatusBarStateController.addListener(this, StatusBarStateController.RANK_STATUS_BAR);
 
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
 
         mDisplay = mWindowManager.getDefaultDisplay();
         updateDisplaySize();
@@ -804,7 +805,6 @@
         mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
         mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
                 R.id.notification_container_parent));
-        mKeyguardStatusBar = mStatusBarWindow.findViewById(R.id.keyguard_header);
 
         mNotificationIconAreaController = SystemUIFactory.getInstance()
                 .createNotificationIconAreaController(context, this);
@@ -865,6 +865,8 @@
         mHeadsUpManager.addListener(mNotificationPanel);
         mHeadsUpManager.addListener(mGroupManager);
         mHeadsUpManager.addListener(mVisualStabilityManager);
+        mAmbientPulseManager.addListener(this);
+        mAmbientPulseManager.addListener(mGroupManager);
         mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
         putComponent(HeadsUpManager.class, mHeadsUpManager);
@@ -977,7 +979,6 @@
                     ((QSFragment) qs).setHost(qsh);
                     mQSPanel = ((QSFragment) qs).getQsPanel();
                     mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
-                    mKeyguardStatusBar.setQSPanel(mQSPanel);
                 }
             });
         }
@@ -1115,8 +1116,6 @@
 
     @Override
     public void onThemeChanged() {
-        // The status bar on the keyguard is a special layout.
-        if (mKeyguardStatusBar != null) mKeyguardStatusBar.onThemeChanged();
         // Recreate Indication controller because internal references changed
         mKeyguardIndicationController =
                 SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
@@ -1151,7 +1150,8 @@
 
     protected void createUserSwitcher() {
         mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
-                mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mKeyguardStatusBar,
+                mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
+                mStatusBarWindow.findViewById(R.id.keyguard_header),
                 mNotificationPanel);
     }
 
@@ -1168,6 +1168,8 @@
                 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);
@@ -1213,17 +1215,18 @@
             int createMode = navbarPos == NAV_BAR_POS_LEFT
                     ? SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT
                     : SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-            return mRecents.splitPrimaryTask(NavigationBarGestureHelper.DRAG_MODE_NONE, createMode,
-                    null, metricsDockAction);
+            return mRecents.splitPrimaryTask(createMode, null, metricsDockAction);
         } else {
             Divider divider = getComponent(Divider.class);
-            if (divider != null && divider.isMinimized() && !divider.isHomeStackResizable()) {
-                // Undocking from the minimized state is not supported
-                return false;
-            } else {
-                EventBus.getDefault().send(new UndockingTaskEvent());
-                if (metricsUndockAction != -1) {
-                    mMetricsLogger.action(metricsUndockAction);
+            if (divider != null) {
+                if (divider.isMinimized() && !divider.isHomeStackResizable()) {
+                    // Undocking from the minimized state is not supported
+                    return false;
+                } else {
+                    divider.onUndockingTask();
+                    if (metricsUndockAction != -1) {
+                        mMetricsLogger.action(metricsUndockAction);
+                    }
                 }
             }
         }
@@ -1233,7 +1236,7 @@
     @Override
     public void onPerformRemoveNotification(StatusBarNotification n) {
         if (mNotificationPanel.hasPulsingNotifications() &&
-                    !mHeadsUpManager.hasNotifications()) {
+                    !mAmbientPulseManager.hasNotifications()) {
             // We were showing a pulse for a notification, but no notifications are pulsing anymore.
             // Finish the pulse.
             mDozeScrimController.pulseOutNow();
@@ -1697,8 +1700,12 @@
     }
 
     @Override
-    public boolean shouldPeek(Entry entry, StatusBarNotification sbn) {
-        if (mIsOccluded && !isDozing()) {
+    public boolean canHeadsUp(Entry entry, StatusBarNotification sbn) {
+        if (isDozing()) {
+            return false;
+        }
+
+        if (mIsOccluded) {
             boolean devicePublic = mLockscreenUserManager.
                     isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
             boolean userPublic = devicePublic
@@ -1711,17 +1718,14 @@
 
         if (!panelsEnabled()) {
             if (DEBUG) {
-                Log.d(TAG, "No peeking: disabled panel : " + sbn.getKey());
+                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 peeking: accessible fullscreen: " + sbn.getKey());
-                return false;
-            } else if (isDozing()) {
-                // We never want heads up when we are dozing.
+                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
@@ -1797,9 +1801,16 @@
     @Override
     public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
         mEntryManager.updateNotificationRanking(null /* rankingMap */);
+    }
 
-        if (isHeadsUp) {
-            mDozeServiceHost.fireNotificationHeadsUp();
+    @Override
+    public void onAmbientStateChanged(Entry entry, boolean isAmbient) {
+        mEntryManager.updateNotificationRanking(null);
+        if (isAmbient) {
+            mDozeServiceHost.fireNotificationPulse();
+        } else if (!mAmbientPulseManager.hasNotifications()) {
+            // There are no longer any notifications to show.  We should end the pulse now.
+            mDozeScrimController.pulseOutNow();
         }
     }
 
@@ -1900,6 +1911,7 @@
         }
     }
 
+    @Override
     public void onLaunchAnimationCancelled() {
         if (!isCollapsing()) {
             onClosingFinished();
@@ -1910,6 +1922,31 @@
         return mHeadsUpAppearanceController.shouldBeVisible();
     }
 
+    @Override
+    public void onExpandAnimationFinished(boolean launchIsFullScreen) {
+        if (!isCollapsing()) {
+            onClosingFinished();
+        }
+        if (launchIsFullScreen) {
+            instantCollapseNotificationPanel();
+        }
+    }
+
+    @Override
+    public void onExpandAnimationTimedOut() {
+        if (isPresenterFullyCollapsed() && !isCollapsing()
+                && !mActivityLaunchAnimator.isLaunchForActivity()) {
+            onClosingFinished();
+        } else {
+            collapsePanel(true /* animate */);
+        }
+    }
+
+    @Override
+    public boolean areLaunchAnimationsEnabled() {
+        return mState == StatusBarState.SHADE;
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
@@ -2145,7 +2182,7 @@
     }
 
     @Override
-    public void animateExpandSettingsPanel(String subPanel) {
+    public void animateExpandSettingsPanel(@Nullable String subPanel) {
         if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
         if (!panelsEnabled()) {
             return;
@@ -2154,7 +2191,6 @@
         // Settings are not available in setup
         if (!mUserSetup) return;
 
-
         if (subPanel != null) {
             mQSPanel.openDetails(subPanel);
         }
@@ -2816,6 +2852,9 @@
                 }
             }
             else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+                if (mStatusBarWindowController != null) {
+                    mStatusBarWindowController.setNotTouchable(false);
+                }
                 finishBarAnimations();
                 resetUserExpandedStates();
             }
@@ -2913,8 +2952,6 @@
         // End old BaseStatusBar.userSwitched
         if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
         animateCollapsePanels();
-        updatePublicMode();
-        mEntryManager.getNotificationData().filterAndSort();
         if (mReinflateNotificationsOnUserSwitched) {
             mEntryManager.updateNotificationsOnDensityOrFontScaleChanged();
             mReinflateNotificationsOnUserSwitched = false;
@@ -3347,7 +3384,9 @@
     }
 
     public boolean isCollapsing() {
-        return mNotificationPanel.isCollapsing() || mActivityLaunchAnimator.isAnimationPending();
+        return mNotificationPanel.isCollapsing()
+                || mActivityLaunchAnimator.isAnimationPending()
+                || mActivityLaunchAnimator.isAnimationRunning();
     }
 
     public void addPostCollapseAction(Runnable r) {
@@ -3453,7 +3492,14 @@
         mIsKeyguard = false;
         Trace.beginSection("StatusBar#hideKeyguard");
         boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
-        mStatusBarStateController.setState(StatusBarState.SHADE);
+        if (!(mStatusBarStateController.setState(StatusBarState.SHADE))) {
+            //TODO: StatusBarStateController should probably know about hiding the keyguard and
+            // notify listeners.
+
+            // If the state didn't change, we may still need to update public mode
+            mLockscreenUserManager.updatePublicMode();
+            mEntryManager.updateNotifications();
+        }
         View viewToClick = null;
         if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
             if (!mKeyguardRequested) {
@@ -3539,34 +3585,6 @@
         mScrimController.setExpansionAffectsAlpha(true);
     }
 
-    // TODO: Move this to NotificationLockscreenUserManager.
-    private void updatePublicMode() {
-        final boolean showingKeyguard = mStatusBarKeyguardViewManager.isShowing();
-        final boolean devicePublic = showingKeyguard
-                && mStatusBarKeyguardViewManager.isSecure(
-                        mLockscreenUserManager.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 = mLockscreenUserManager.getCurrentProfiles();
-        for (int i = currentProfiles.size() - 1; i >= 0; i--) {
-            final int userId = currentProfiles.valueAt(i).id;
-            boolean isProfilePublic = devicePublic;
-            if (!devicePublic && userId != mLockscreenUserManager.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)
-                        && mStatusBarKeyguardViewManager.isSecure(userId)) {
-                    isProfilePublic = mKeyguardManager.isDeviceLocked(userId);
-                }
-            }
-            mLockscreenUserManager.setLockscreenPublicMode(isProfilePublic, userId);
-        }
-    }
-
     /**
      * Switches theme from light to dark and vice-versa.
      */
@@ -3596,6 +3614,7 @@
         mKeyguardIndicationController.setDozing(mDozing);
         mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation);
         mNotificationLogger.setDozing(mDozing);
+        mGroupManager.setDozing(mDozing);
         updateQsExpansionEnabled();
         Trace.endSection();
     }
@@ -3756,8 +3775,6 @@
             }
         }
         updateDozingState();
-        updatePublicMode();
-        mEntryManager.updateNotifications();
         checkBarModes();
         updateScrimController();
         updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
@@ -4010,8 +4027,6 @@
 
     @Override
     public void onWorkChallengeChanged() {
-        updatePublicMode();
-        mEntryManager.updateNotifications();
         if (mPendingWorkRemoteInputView != null
                 && !mLockscreenUserManager.isAnyProfilePublicMode()) {
             // Expand notification panel and the notification row, then click on remote input view
@@ -4142,6 +4157,7 @@
         @Override
         public void onStartedWakingUp() {
             mDeviceInteractive = true;
+            mAmbientPulseManager.releaseAllImmediately();
             mVisualStabilityManager.setScreenOn(true);
             mNotificationPanel.setTouchAndAnimationDisabled(false);
             mDozeServiceHost.stopDozing();
@@ -4174,11 +4190,7 @@
         public void onScreenTurnedOff() {
             mFalsingManager.onScreenOff();
             mScrimController.onScreenTurnedOff();
-            // If we pulse in from AOD, we turn the screen off first. However, updatingIsKeyguard
-            // in that case destroys the HeadsUpManager state, so don't do it in that case.
-            if (!isPulsing()) {
-                updateIsKeyguard();
-            }
+            updateIsKeyguard();
         }
     };
 
@@ -4238,12 +4250,12 @@
 
     @Override
     public void appTransitionCancelled() {
-        EventBus.getDefault().send(new AppTransitionFinishedEvent());
+        getComponent(Divider.class).onAppTransitionFinished();
     }
 
     @Override
     public void appTransitionFinished() {
-        EventBus.getDefault().send(new AppTransitionFinishedEvent());
+        getComponent(Divider.class).onAppTransitionFinished();
     }
 
     @Override
@@ -4417,9 +4429,9 @@
             }
         }
 
-        public void fireNotificationHeadsUp() {
+        public void fireNotificationPulse() {
             for (Callback callback : mCallbacks) {
-                callback.onNotificationHeadsUp();
+                callback.onNotificationAlerted();
             }
         }
 
@@ -4455,7 +4467,7 @@
                 @Override
                 public void onPulseStarted() {
                     callback.onPulseStarted();
-                    if (mHeadsUpManager.hasNotifications()) {
+                    if (mAmbientPulseManager.hasNotifications()) {
                         // Only pulse the stack scroller if there's actually something to show.
                         // Otherwise just show the always-on screen.
                         setPulsing(true);
@@ -4536,7 +4548,11 @@
 
         @Override
         public void extendPulse() {
-            mDozeScrimController.extendPulse();
+            if (mDozeScrimController.isPulsing() && mAmbientPulseManager.hasNotifications()) {
+                mAmbientPulseManager.extendPulse();
+            } else {
+                mDozeScrimController.extendPulse();
+            }
         }
 
         @Override
@@ -4622,6 +4638,8 @@
     // for heads up notifications
     protected HeadsUpManagerPhone mHeadsUpManager;
 
+    protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
+
     private AboveShelfObserver mAboveShelfObserver;
 
     // handling reordering
@@ -4649,6 +4667,7 @@
 
     protected WindowManager mWindowManager;
     protected IWindowManager mWindowManagerService;
+    private IDreamManager mDreamManager;
 
     protected Display mDisplay;
 
@@ -4721,13 +4740,14 @@
                 : notification.fullScreenIntent;
         final String notificationKey = sbn.getKey();
 
-        final boolean afterKeyguardGone = intent.isActivity()
+        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.contains(notificationKey)) {
+            if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(notificationKey)) {
                 // Release the HUN notification to the shade.
 
                 if (isPresenterFullyCollapsed()) {
@@ -4762,7 +4782,7 @@
                     // 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 (intent.isActivity()) {
+                    if (isActivityIntent) {
                         final int userId = intent.getCreatorUserHandle().getIdentifier();
                         if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
                                 && mKeyguardManager.isDeviceLocked(userId)) {
@@ -4798,7 +4818,7 @@
                         }
                         launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
                                 null, null, getActivityOptions(adapter));
-                        mActivityLaunchAnimator.setLaunchResult(launchResult);
+                        mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
                     } catch (RemoteException | PendingIntent.CanceledException e) {
                         // the stack trace isn't very helpful here.
                         // Just log the exception message.
@@ -4806,7 +4826,7 @@
 
                         // TODO: Dismiss Keyguard.
                     }
-                    if (intent.isActivity()) {
+                    if (isActivityIntent) {
                         mAssistManager.hideAssist();
                     }
                 }
@@ -4925,7 +4945,7 @@
                         .startActivities(getActivityOptions(
                                 mActivityLaunchAnimator.getLaunchAnimation(row, mIsOccluded)),
                                 new UserHandle(UserHandle.getUserId(appUid)));
-                mActivityLaunchAnimator.setLaunchResult(launchResult);
+                mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */);
                 if (shouldCollapse()) {
                     // Putting it back on the main thread, since we're touching views
                     mStatusBarWindow.post(() -> animateCollapsePanels(
@@ -4952,7 +4972,13 @@
     }
 
     void awakenDreams() {
-        SystemServicesProxy.getInstance(mContext).awakenDreamsAsync();
+        Dependency.get(UiOffloadThread.class).submit(() -> {
+            try {
+                mDreamManager.awaken();
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        });
     }
 
     @Override
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 e8389af..3db1456 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -460,6 +460,11 @@
                 boolean staying = mStatusBar.hideKeyguard();
                 if (!staying) {
                     mStatusBarWindowController.setKeyguardFadingAway(true);
+                    // hide() will happen asynchronously and might arrive after the scrims
+                    // were already hidden, this means that the transition callback won't
+                    // be triggered anymore and StatusBarWindowController will be forever in
+                    // the fadingAway state.
+                    mStatusBar.updateScrimController();
                     wakeAndUnlockDejank();
                 } else {
                     mStatusBar.finishKeyguardFadingAway();
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 51a5df2..57c7e28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -93,7 +93,8 @@
         mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
         mDozeParameters = dozeParameters;
         mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).addListener(
+                mStateListener, StatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
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/ExtensionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
index 6d75cfc..a6146a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
@@ -22,7 +22,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -71,7 +71,7 @@
 
         @Override
         public <P extends T> ExtensionController.ExtensionBuilder<T> withPlugin(Class<P> cls) {
-            return withPlugin(cls, PluginManager.getAction(cls));
+            return withPlugin(cls, PluginManager.Helper.getAction(cls));
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index e9efaa1..0a72c3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -17,10 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.os.UserManager;
@@ -38,14 +35,13 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArrayList<Callback> mCallbacks = new ArrayList<>();
-    private final WifiStateReceiver mWifiStateReceiver = new WifiStateReceiver();
     private final ConnectivityManager mConnectivityManager;
     private final WifiManager mWifiManager;
     private final Context mContext;
 
     private int mHotspotState;
     private int mNumConnectedDevices;
-    private boolean mWaitingForCallback;
+    private boolean mWaitingForTerminalState;
 
     public HotspotControllerImpl(Context context) {
         mContext = context;
@@ -63,7 +59,9 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("HotspotController state:");
-        pw.print("  mHotspotEnabled="); pw.println(stateToString(mHotspotState));
+        pw.print("  mHotspotState="); pw.println(stateToString(mHotspotState));
+        pw.print("  mNumConnectedDevices="); pw.println(mNumConnectedDevices);
+        pw.print("  mWaitingForTerminalState="); pw.println(mWaitingForTerminalState);
     }
 
     private static String stateToString(int hotspotState) {
@@ -99,7 +97,6 @@
         if (DEBUG) Log.d(TAG, "removeCallback " + callback);
         synchronized (mCallbacks) {
             mCallbacks.remove(callback);
-
             updateWifiStateListeners(!mCallbacks.isEmpty());
         }
     }
@@ -112,7 +109,6 @@
      * @param shouldListen whether we should start listening to various wifi statuses
      */
     private void updateWifiStateListeners(boolean shouldListen) {
-        mWifiStateReceiver.setListening(shouldListen);
         if (shouldListen) {
             mWifiManager.registerSoftApCallback(
                     this,
@@ -129,21 +125,27 @@
 
     @Override
     public boolean isHotspotTransient() {
-        return mWaitingForCallback || (mHotspotState == WifiManager.WIFI_AP_STATE_ENABLING);
+        return mWaitingForTerminalState || (mHotspotState == WifiManager.WIFI_AP_STATE_ENABLING);
     }
 
     @Override
     public void setHotspotEnabled(boolean enabled) {
-        if (mWaitingForCallback) {
-            if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for callback.");
+        if (mWaitingForTerminalState) {
+            if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for terminal state.");
             return;
         }
         if (enabled) {
-            OnStartTetheringCallback callback = new OnStartTetheringCallback();
-            mWaitingForCallback = true;
+            mWaitingForTerminalState = true;
             if (DEBUG) Log.d(TAG, "Starting tethering");
-            mConnectivityManager.startTethering(
-                    ConnectivityManager.TETHERING_WIFI, false, callback);
+            mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, false,
+                    new ConnectivityManager.OnStartTetheringCallback() {
+                        @Override
+                        public void onTetheringFailed() {
+                            if (DEBUG) Log.d(TAG, "onTetheringFailed");
+                            maybeResetSoftApState();
+                            fireHotspotChangedCallback();
+                        }
+                    });
         } else {
             mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
         }
@@ -155,99 +157,56 @@
     }
 
     /**
-     * Sends a hotspot changed callback with the new enabled status. Wraps
-     * {@link #fireHotspotChangedCallback(boolean, int)} and assumes that the number of devices has
-     * not changed.
-     *
-     * @param enabled whether the hotspot is enabled
+     * Sends a hotspot changed callback.
+     * Be careful when calling over multiple threads, especially if one of them is the main thread
+     * (as it can be blocked).
      */
-    private void fireHotspotChangedCallback(boolean enabled) {
-        fireHotspotChangedCallback(enabled, mNumConnectedDevices);
-    }
-
-    /**
-     * Sends a hotspot changed callback with the new enabled status & the number of devices
-     * connected to the hotspot. Be careful when calling over multiple threads, especially if one of
-     * them is the main thread (as it can be blocked).
-     *
-     * @param enabled whether the hotspot is enabled
-     * @param numConnectedDevices number of devices connected to the hotspot
-     */
-    private void fireHotspotChangedCallback(boolean enabled, int numConnectedDevices) {
+    private void fireHotspotChangedCallback() {
         synchronized (mCallbacks) {
             for (Callback callback : mCallbacks) {
-                callback.onHotspotChanged(enabled, numConnectedDevices);
+                callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices);
             }
         }
     }
 
     @Override
     public void onStateChanged(int state, int failureReason) {
-        // Do nothing - we don't care about changing anything here.
+        // Update internal hotspot state for tracking before using any enabled/callback methods.
+        mHotspotState = state;
+
+        maybeResetSoftApState();
+        if (!isHotspotEnabled()) {
+            // Reset num devices if the hotspot is no longer enabled so we don't get ghost
+            // counters.
+            mNumConnectedDevices = 0;
+        }
+
+        fireHotspotChangedCallback();
+    }
+
+    private void maybeResetSoftApState() {
+        if (!mWaitingForTerminalState) {
+            return; // Only reset soft AP state if enabled from this controller.
+        }
+        switch (mHotspotState) {
+            case WifiManager.WIFI_AP_STATE_FAILED:
+                // TODO(b/110697252): must be called to reset soft ap state after failure
+                mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
+                // Fall through
+            case WifiManager.WIFI_AP_STATE_ENABLED:
+            case WifiManager.WIFI_AP_STATE_DISABLED:
+                mWaitingForTerminalState = false;
+                break;
+            case WifiManager.WIFI_AP_STATE_ENABLING:
+            case WifiManager.WIFI_AP_STATE_DISABLING:
+            default:
+                break;
+        }
     }
 
     @Override
     public void onNumClientsChanged(int numConnectedDevices) {
         mNumConnectedDevices = numConnectedDevices;
-        fireHotspotChangedCallback(isHotspotEnabled(), numConnectedDevices);
-    }
-
-    private final class OnStartTetheringCallback extends
-            ConnectivityManager.OnStartTetheringCallback {
-        @Override
-        public void onTetheringStarted() {
-            if (DEBUG) Log.d(TAG, "onTetheringStarted");
-            mWaitingForCallback = false;
-            // Don't fire a callback here, instead wait for the next update from wifi.
-        }
-
-        @Override
-        public void onTetheringFailed() {
-            if (DEBUG) Log.d(TAG, "onTetheringFailed");
-            mWaitingForCallback = false;
-            // TODO(b/110697252): stopTethering must be called to reset soft ap state after failure
-            mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
-            fireHotspotChangedCallback(isHotspotEnabled());
-          // TODO: Show error.
-        }
-    }
-
-    /**
-     * Class to listen in on wifi state and update the hotspot state
-     */
-    private final class WifiStateReceiver extends BroadcastReceiver {
-        private boolean mRegistered;
-
-        public void setListening(boolean listening) {
-            if (listening && !mRegistered) {
-                if (DEBUG) Log.d(TAG, "Registering receiver");
-                final IntentFilter filter = new IntentFilter();
-                filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
-                mContext.registerReceiver(this, filter);
-                mRegistered = true;
-            } else if (!listening && mRegistered) {
-                if (DEBUG) Log.d(TAG, "Unregistering receiver");
-                mContext.unregisterReceiver(this);
-                mRegistered = false;
-            }
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int state = intent.getIntExtra(
-                    WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
-            if (DEBUG) Log.d(TAG, "onReceive " + state);
-
-            // Update internal hotspot state for tracking before using any enabled/callback methods.
-            mHotspotState = state;
-
-            if (!isHotspotEnabled()) {
-                // Reset num devices if the hotspot is no longer enabled so we don't get ghost
-                // counters.
-                mNumConnectedDevices = 0;
-            }
-
-            fireHotspotChangedCallback(isHotspotEnabled());
-        }
+        fireHotspotChangedCallback();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
index 945d9b9..2340786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
@@ -19,6 +19,7 @@
 import android.animation.ArgbEvaluator;
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -35,6 +36,7 @@
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.FloatProperty;
+import android.view.ContextThemeWrapper;
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 
@@ -388,6 +390,23 @@
         }
     }
 
+    /**
+     * Creates a KeyButtonDrawable with a shadow given its icon. The tint applied to the drawable
+     * is determined by the dark and light theme given by the context.
+     * @param ctx Context to get the drawable and determine the dark and light theme
+     * @param icon the icon resource id
+     * @param hasShadow if a shadow will appear with the drawable
+     * @return KeyButtonDrawable
+     */
+    public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
+        boolean hasShadow) {
+        final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
+        Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
+        Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
+        return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow);
+    }
+
     public static KeyButtonDrawable create(Context lightContext, Context darkContext,
         @DrawableRes int iconResId, boolean hasShadow) {
         return create(lightContext,
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/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index cf39404..24a28cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -668,6 +668,7 @@
         Locale current = mContext.getResources().getConfiguration().locale;
         if (!current.equals(mLocale)) {
             mLocale = current;
+            mWifiSignalController.refreshLocale();
             notifyAllListeners();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 52b813f..7dd0d0f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -586,7 +586,8 @@
             final InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
 
             if (mShowImeOnInputConnection && inputConnection != null) {
-                final InputMethodManager imm = InputMethodManager.getInstance();
+                final InputMethodManager imm =
+                        getContext().getSystemService(InputMethodManager.class);
                 if (imm != null) {
                     // onCreateInputConnection is called by InputMethodManager in the middle of
                     // setting up the connection to the IME; wait with requesting the IME until that
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 0adb439..29a6b95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -403,7 +403,7 @@
                 boolean hasCACerts = !(conn.getService().getUserCaAliases().getList().isEmpty());
                 return new Pair<Integer, Boolean>(userId[0], hasCACerts);
             } catch (RemoteException | InterruptedException | AssertionError e) {
-                Log.i(TAG, e.getMessage());
+                Log.i(TAG, "failed to get CA certs", e);
                 new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed(
                         () -> new CACertLoader().execute(userId[0]),
                         CA_CERT_LOADING_RETRY_TIME_IN_MS);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 0233ad1..693df88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -73,6 +73,10 @@
         return new WifiState();
     }
 
+    void refreshLocale() {
+        mWifiTracker.refreshLocale();
+    }
+
     @Override
     public void notifyListeners(SignalCallback callback) {
         // only show wifi in the cluster if connected or if wifi-only
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index ef51bf0..8d2552f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -55,6 +55,7 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArrayList<Callback> mCallbacks = new ArrayList<>();
+    private final Object mCallbacksLock = new Object();
     private final Context mContext;
     private final GlobalSetting mModeSetting;
     private final GlobalSetting mConfigSetting;
@@ -114,12 +115,16 @@
 
     @Override
     public void addCallback(Callback callback) {
-        mCallbacks.add(callback);
+        synchronized (mCallbacksLock) {
+            mCallbacks.add(callback);
+        }
     }
 
     @Override
     public void removeCallback(Callback callback) {
-        mCallbacks.remove(callback);
+        synchronized (mCallbacksLock) {
+            mCallbacks.remove(callback);
+        }
     }
 
     @Override
@@ -183,28 +188,40 @@
     }
 
     private void fireNextAlarmChanged() {
-        Utils.safeForeach(mCallbacks, c -> c.onNextAlarmChanged());
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onNextAlarmChanged());
+        }
     }
 
     private void fireEffectsSuppressorChanged() {
-        Utils.safeForeach(mCallbacks, c -> c.onEffectsSupressorChanged());
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onEffectsSupressorChanged());
+        }
     }
 
     private void fireZenChanged(int zen) {
-        Utils.safeForeach(mCallbacks, c -> c.onZenChanged(zen));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onZenChanged(zen));
+        }
     }
 
     private void fireZenAvailableChanged(boolean available) {
-        Utils.safeForeach(mCallbacks, c -> c.onZenAvailableChanged(available));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onZenAvailableChanged(available));
+        }
     }
 
     private void fireManualRuleChanged(ZenRule rule) {
-        Utils.safeForeach(mCallbacks, c -> c.onManualRuleChanged(rule));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onManualRuleChanged(rule));
+        }
     }
 
     @VisibleForTesting
     protected void fireConfigChanged(ZenModeConfig config) {
-        Utils.safeForeach(mCallbacks, c -> c.onConfigChanged(config));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onConfigChanged(config));
+        }
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
index c294806..0826054 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
@@ -25,29 +25,32 @@
 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.PluginInstanceManager;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.plugins.PluginPrefs;
+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;
 
-import java.util.ArrayList;
 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) {
@@ -69,6 +72,7 @@
 
     @Override
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        mPluginEnabler = new PluginEnablerImpl(getContext());
         loadPrefs();
     }
 
@@ -99,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);
         });
@@ -140,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);
         }
@@ -157,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;
                 }
             }
@@ -166,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/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 088630f..5aa3035 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -32,7 +32,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
-import com.android.systemui.plugins.PluginPrefs;
+import com.android.systemui.shared.plugins.PluginPrefs;
 
 public class TunerFragment extends PreferenceFragment {
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 13c43f7..4810b0b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,6 +18,7 @@
 
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
+import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.media.AudioManager.RINGER_MODE_NORMAL;
 import static android.media.AudioManager.RINGER_MODE_SILENT;
 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
@@ -34,6 +35,7 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.animation.ObjectAnimator;
 import android.annotation.SuppressLint;
+import android.app.ActivityManager;
 import android.app.Dialog;
 import android.app.KeyguardManager;
 import android.content.ContentResolver;
@@ -129,6 +131,7 @@
     private ConfigurableTexts mConfigurableTexts;
     private final SparseBooleanArray mDynamic = new SparseBooleanArray();
     private final KeyguardManager mKeyguard;
+    private final ActivityManager mActivityManager;
     private final AccessibilityManagerWrapper mAccessibilityMgr;
     private final Object mSafetyWarningLock = new Object();
     private final Accessibility mAccessibility = new Accessibility();
@@ -154,6 +157,7 @@
         mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mController = Dependency.get(VolumeDialogController.class);
         mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
         mShowActiveStreamOnly = showActiveStreamOnly();
@@ -431,7 +435,9 @@
     public void initSettingsH() {
         if (mSettingsView != null) {
             mSettingsView.setVisibility(
-                    mDeviceProvisionedController.isCurrentUserSetup() ? VISIBLE : GONE);
+                    mDeviceProvisionedController.isCurrentUserSetup() &&
+                            mActivityManager.getLockTaskModeState() == LOCK_TASK_MODE_NONE ?
+                            VISIBLE : GONE);
         }
         if (mSettingsIcon != null) {
             mSettingsIcon.setOnClickListener(v -> {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index e6e4857..62ca3f3 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -40,7 +40,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
new file mode 100644
index 0000000..cfe9818
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard
+
+import android.support.test.filters.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class KeyguardPatternViewTest : SysuiTestCase() {
+
+    private lateinit var mKeyguardPatternView: KeyguardPatternView
+    private lateinit var mSecurityMessage: KeyguardMessageArea
+
+    @Before
+    fun setup() {
+        val inflater = LayoutInflater.from(context)
+        mKeyguardPatternView = inflater.inflate(R.layout.keyguard_pattern_view, null)
+                as KeyguardPatternView
+        mSecurityMessage = KeyguardMessageArea.findSecurityMessageDisplay(mKeyguardPatternView)
+                as KeyguardMessageArea
+    }
+
+    @Test
+    fun onResume_clearsTextField() {
+        mSecurityMessage.setMessage("an old message")
+        mKeyguardPatternView.onResume(KeyguardSecurityView.SCREEN_ON)
+        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/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/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index eaa0dcf..1cf73b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -33,6 +33,7 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import android.content.Intent;
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -71,7 +72,8 @@
         mSensor = mSensorManager.getFakeLightSensor();
         mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
                 mSensor.getSensor(), mHostFake, null /* handler */,
-                DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY);
+                DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY,
+                true /* debuggable */);
     }
 
     @Test
@@ -93,6 +95,19 @@
     }
 
     @Test
+    public void testAod_usesDebugValue() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        Intent intent = new Intent(DozeScreenBrightness.ACTION_AOD_BRIGHTNESS);
+        intent.putExtra(DozeScreenBrightness.BRIGHTNESS_BUCKET, 1);
+        mScreen.onReceive(mContext, intent);
+        mSensor.sendSensorEvent(3);
+
+        assertEquals(1, mServiceFake.screenBrightness);
+    }
+
+    @Test
     public void testAod_usesLightSensorRespectingUserSetting() throws Exception {
         int maxBrightness = 3;
         Settings.System.putIntForUser(mContext.getContentResolver(),
@@ -160,7 +175,8 @@
     public void testNullSensor() throws Exception {
         mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
                 null /* sensor */, mHostFake, null /* handler */,
-                DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY);
+                DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY,
+                true /* debuggable */);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE_AOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index c2da7f5..5c8336c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -88,14 +88,14 @@
         mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
         mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
 
-        mHost.callback.onNotificationHeadsUp();
+        mHost.callback.onNotificationAlerted();
 
         mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
 
         verify(mMachine, never()).requestState(any());
         verify(mMachine, never()).requestPulse(anyInt());
 
-        mHost.callback.onNotificationHeadsUp();
+        mHost.callback.onNotificationAlerted();
 
         mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
index f8aa28d..199c4c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
@@ -40,9 +40,9 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -65,7 +65,7 @@
     private @Mock IActivityTaskManager mIActivityTaskManager;
 
     private WorkLockActivityController mController;
-    private SysUiTaskStackChangeListener mTaskStackListener;
+    private TaskStackChangeListener mTaskStackListener;
 
     @Before
     public void setUp() throws Exception {
@@ -75,8 +75,8 @@
         doReturn("com.example.test").when(mContext).getPackageName();
 
         // Construct controller. Save the TaskStackListener for injecting events.
-        final ArgumentCaptor<SysUiTaskStackChangeListener> listenerCaptor =
-                ArgumentCaptor.forClass(SysUiTaskStackChangeListener.class);
+        final ArgumentCaptor<TaskStackChangeListener> listenerCaptor =
+                ArgumentCaptor.forClass(TaskStackChangeListener.class);
         mController = new WorkLockActivityController(mContext, mActivityManager,
                 mIActivityTaskManager);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginInstanceManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginInstanceManagerTest.java
deleted file mode 100644
index 04441ab..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginInstanceManagerTest.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
-import com.android.systemui.plugins.VersionInfo.InvalidVersionException;
-import com.android.systemui.plugins.annotations.Requires;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import android.app.Activity;
-import android.app.NotificationManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.HandlerThread;
-import android.os.UserHandle;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class PluginInstanceManagerTest extends SysuiTestCase {
-
-    // Static since the plugin needs to be generated by the PluginInstanceManager using newInstance.
-    private static Plugin sMockPlugin;
-
-    private HandlerThread mHandlerThread;
-    private Context mContextWrapper;
-    private PackageManager mMockPm;
-    private PluginListener mMockListener;
-    private PluginInstanceManager mPluginInstanceManager;
-    private PluginManagerImpl mMockManager;
-    private VersionInfo mMockVersionInfo;
-
-    @Before
-    public void setup() throws Exception {
-        mHandlerThread = new HandlerThread("test_thread");
-        mHandlerThread.start();
-        mContextWrapper = new MyContextWrapper(getContext());
-        mMockPm = mock(PackageManager.class);
-        mMockListener = mock(PluginListener.class);
-        mMockManager = mock(PluginManagerImpl.class);
-        when(mMockManager.getClassLoader(any(), any()))
-                .thenReturn(getClass().getClassLoader());
-        mMockVersionInfo = mock(VersionInfo.class);
-        mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
-                mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
-                mMockManager, true);
-        sMockPlugin = mock(Plugin.class);
-        when(sMockPlugin.getVersion()).thenReturn(1);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mHandlerThread.quit();
-        sMockPlugin = null;
-    }
-
-    @UiThreadTest
-    @Test
-    public void testGetPlugin() throws Exception {
-        setupFakePmQuery();
-        PluginInfo p = mPluginInstanceManager.getPlugin();
-        assertNotNull(p.mPlugin);
-        verify(sMockPlugin).onCreate(any(), any());
-    }
-
-    @Test
-    public void testNoPlugins() throws Exception {
-        when(mMockPm.queryIntentServices(any(), anyInt())).thenReturn(
-                Collections.emptyList());
-        mPluginInstanceManager.loadAll();
-
-        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
-        waitForIdleSync(mPluginInstanceManager.mMainHandler);
-
-        verify(mMockListener, Mockito.never()).onPluginConnected(any(), any());
-    }
-
-    @Test
-    public void testPluginCreate() throws Exception {
-        createPlugin();
-
-        // Verify startup lifecycle
-        verify(sMockPlugin).onCreate(ArgumentCaptor.forClass(Context.class).capture(),
-                ArgumentCaptor.forClass(Context.class).capture());
-        verify(mMockListener).onPluginConnected(any(), any());
-    }
-
-    @Test
-    public void testPluginDestroy() throws Exception {
-        createPlugin(); // Get into valid created state.
-
-        mPluginInstanceManager.destroy();
-
-        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
-        waitForIdleSync(mPluginInstanceManager.mMainHandler);
-
-        // Verify shutdown lifecycle
-        verify(mMockListener).onPluginDisconnected(ArgumentCaptor.forClass(Plugin.class).capture());
-        verify(sMockPlugin).onDestroy();
-    }
-
-    @Test
-    public void testIncorrectVersion() throws Exception {
-        NotificationManager nm = mock(NotificationManager.class);
-        mContext.addMockSystemService(Context.NOTIFICATION_SERVICE, nm);
-        setupFakePmQuery();
-        doThrow(new InvalidVersionException("", false)).when(mMockVersionInfo).checkVersion(any());
-
-        mPluginInstanceManager.loadAll();
-
-        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
-        waitForIdleSync(mPluginInstanceManager.mMainHandler);
-
-        // Plugin shouldn't be connected because it is the wrong version.
-        verify(mMockListener, Mockito.never()).onPluginConnected(any(), any());
-        verify(nm).notifyAsUser(eq(TestPlugin.class.getName()), eq(SystemMessage.NOTE_PLUGIN),
-                any(), eq(UserHandle.ALL));
-    }
-
-    @Test
-    public void testReloadOnChange() throws Exception {
-        createPlugin(); // Get into valid created state.
-
-        mPluginInstanceManager.onPackageChange("com.android.systemui");
-
-        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
-        waitForIdleSync(mPluginInstanceManager.mMainHandler);
-
-        // Verify the old one was destroyed.
-        verify(mMockListener).onPluginDisconnected(ArgumentCaptor.forClass(Plugin.class).capture());
-        verify(sMockPlugin).onDestroy();
-        // Also verify we got a second onCreate.
-        verify(sMockPlugin, Mockito.times(2)).onCreate(
-                ArgumentCaptor.forClass(Context.class).capture(),
-                ArgumentCaptor.forClass(Context.class).capture());
-        verify(mMockListener, Mockito.times(2)).onPluginConnected(any(), any());
-    }
-
-    @Test
-    public void testNonDebuggable() throws Exception {
-        // Create a version that thinks the build is not debuggable.
-        mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
-                mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
-                mMockManager, false);
-        setupFakePmQuery();
-
-        mPluginInstanceManager.loadAll();
-
-        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
-        waitForIdleSync(mPluginInstanceManager.mMainHandler);;
-
-        // Non-debuggable build should receive no plugins.
-        verify(mMockListener, Mockito.never()).onPluginConnected(any(), any());
-    }
-
-    @Test
-    public void testCheckAndDisable() throws Exception {
-        createPlugin(); // Get into valid created state.
-
-        // Start with an unrelated class.
-        boolean result = mPluginInstanceManager.checkAndDisable(Activity.class.getName());
-        assertFalse(result);
-        verify(mMockPm, Mockito.never()).setComponentEnabledSetting(
-                ArgumentCaptor.forClass(ComponentName.class).capture(),
-                ArgumentCaptor.forClass(int.class).capture(),
-                ArgumentCaptor.forClass(int.class).capture());
-
-        // Now hand it a real class and make sure it disables the plugin.
-        result = mPluginInstanceManager.checkAndDisable(TestPlugin.class.getName());
-        assertTrue(result);
-        verify(mMockPm).setComponentEnabledSetting(
-                ArgumentCaptor.forClass(ComponentName.class).capture(),
-                ArgumentCaptor.forClass(int.class).capture(),
-                ArgumentCaptor.forClass(int.class).capture());
-    }
-
-    @Test
-    public void testDisableAll() throws Exception {
-        createPlugin(); // Get into valid created state.
-
-        mPluginInstanceManager.disableAll();
-
-        verify(mMockPm).setComponentEnabledSetting(
-                ArgumentCaptor.forClass(ComponentName.class).capture(),
-                ArgumentCaptor.forClass(int.class).capture(),
-                ArgumentCaptor.forClass(int.class).capture());
-    }
-
-    private void setupFakePmQuery() throws Exception {
-        List<ResolveInfo> list = new ArrayList<>();
-        ResolveInfo info = new ResolveInfo();
-        info.serviceInfo = mock(ServiceInfo.class);
-        info.serviceInfo.packageName = "com.android.systemui";
-        info.serviceInfo.name = TestPlugin.class.getName();
-        when(info.serviceInfo.loadLabel(any())).thenReturn("Test Plugin");
-        list.add(info);
-        when(mMockPm.queryIntentServices(any(), Mockito.anyInt())).thenReturn(list);
-        when(mMockPm.getServiceInfo(any(), anyInt())).thenReturn(info.serviceInfo);
-
-        when(mMockPm.checkPermission(Mockito.anyString(), Mockito.anyString())).thenReturn(
-                PackageManager.PERMISSION_GRANTED);
-
-        ApplicationInfo appInfo = getContext().getApplicationInfo();
-        when(mMockPm.getApplicationInfo(Mockito.anyString(), Mockito.anyInt())).thenReturn(
-                appInfo);
-    }
-
-    private void createPlugin() throws Exception {
-        setupFakePmQuery();
-
-        mPluginInstanceManager.loadAll();
-
-        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
-        waitForIdleSync(mPluginInstanceManager.mMainHandler);
-    }
-
-    // Real context with no registering/unregistering of receivers.
-    private static class MyContextWrapper extends ContextWrapper {
-        public MyContextWrapper(Context base) {
-            super(base);
-        }
-
-        @Override
-        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
-            return null;
-        }
-
-        @Override
-        public void unregisterReceiver(BroadcastReceiver receiver) {
-        }
-
-        @Override
-        public void sendBroadcast(Intent intent) {
-            // Do nothing.
-        }
-    }
-
-    // This target class doesn't matter, it just needs to have a Requires to hit the flow where
-    // the mock version info is called.
-    @Requires(target = PluginManagerTest.class, version = 1)
-    public static class TestPlugin implements Plugin {
-        @Override
-        public int getVersion() {
-            return sMockPlugin.getVersion();
-        }
-
-        @Override
-        public void onCreate(Context sysuiContext, Context pluginContext) {
-            sMockPlugin.onCreate(sysuiContext, pluginContext);
-        }
-
-        @Override
-        public void onDestroy() {
-            sMockPlugin.onDestroy();
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
deleted file mode 100644
index 94dbc2a..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.systemui.plugins;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.systemui.Dependency;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
-import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.lang.Thread.UncaughtExceptionHandler;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-public class PluginManagerTest extends SysuiTestCase {
-
-    private PluginInstanceManagerFactory mMockFactory;
-    private PluginInstanceManager mMockPluginInstance;
-    private PluginManagerImpl mPluginManager;
-    private PluginListener mMockListener;
-
-    private UncaughtExceptionHandler mRealExceptionHandler;
-    private UncaughtExceptionHandler mMockExceptionHandler;
-    private UncaughtExceptionHandler mPluginExceptionHandler;
-
-    @Before
-    public void setup() throws Exception {
-        mDependency.injectTestDependency(Dependency.BG_LOOPER,
-                TestableLooper.get(this).getLooper());
-        mRealExceptionHandler = Thread.getUncaughtExceptionPreHandler();
-        mMockExceptionHandler = mock(UncaughtExceptionHandler.class);
-        mMockFactory = mock(PluginInstanceManagerFactory.class);
-        mMockPluginInstance = mock(PluginInstanceManager.class);
-        when(mMockFactory.createPluginInstanceManager(Mockito.any(), Mockito.any(), Mockito.any(),
-                Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any()))
-                .thenReturn(mMockPluginInstance);
-        mPluginManager = new PluginManagerImpl(getContext(), mMockFactory, true,
-                mMockExceptionHandler);
-        resetExceptionHandler();
-        mMockListener = mock(PluginListener.class);
-    }
-
-    @RunWithLooper(setAsMainLooper = true)
-    @Test
-    public void testOneShot() {
-        Plugin mockPlugin = mock(Plugin.class);
-        when(mMockPluginInstance.getPlugin()).thenReturn(new PluginInfo(null, null, mockPlugin,
-                null, null));
-        Plugin result = mPluginManager.getOneShotPlugin("myAction", TestPlugin.class);
-        assertTrue(result == mockPlugin);
-    }
-
-    @Test
-    public void testAddListener() {
-        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
-
-        verify(mMockPluginInstance).loadAll();
-    }
-
-    @Test
-    public void testRemoveListener() {
-        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
-
-        mPluginManager.removePluginListener(mMockListener);
-        verify(mMockPluginInstance).destroy();
-    }
-
-    @Test
-    public void testNonDebuggable() {
-        mPluginManager = new PluginManagerImpl(getContext(), mMockFactory, false,
-                mMockExceptionHandler);
-        resetExceptionHandler();
-
-        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
-        verify(mMockPluginInstance, Mockito.never()).loadAll();
-
-        assertNull(mPluginManager.getOneShotPlugin("myPlugin", TestPlugin.class));
-        verify(mMockPluginInstance, Mockito.never()).getPlugin();
-    }
-
-    @Test
-    public void testExceptionHandler_foundPlugin() {
-        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
-        when(mMockPluginInstance.checkAndDisable(Mockito.any())).thenReturn(true);
-
-        mPluginExceptionHandler.uncaughtException(Thread.currentThread(), new Throwable());
-
-        verify(mMockPluginInstance, Mockito.atLeastOnce()).checkAndDisable(
-                ArgumentCaptor.forClass(String.class).capture());
-        verify(mMockPluginInstance, Mockito.never()).disableAll();
-        verify(mMockExceptionHandler).uncaughtException(
-                ArgumentCaptor.forClass(Thread.class).capture(),
-                ArgumentCaptor.forClass(Throwable.class).capture());
-    }
-
-    @Test
-    public void testExceptionHandler_noFoundPlugin() {
-        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
-        when(mMockPluginInstance.checkAndDisable(Mockito.any())).thenReturn(false);
-
-        mPluginExceptionHandler.uncaughtException(Thread.currentThread(), new Throwable());
-
-        verify(mMockPluginInstance, Mockito.atLeastOnce()).checkAndDisable(
-                ArgumentCaptor.forClass(String.class).capture());
-        verify(mMockPluginInstance).disableAll();
-        verify(mMockExceptionHandler).uncaughtException(
-                ArgumentCaptor.forClass(Thread.class).capture(),
-                ArgumentCaptor.forClass(Throwable.class).capture());
-    }
-
-    @Test
-    public void testDisableIntent() {
-        NotificationManager nm = mock(NotificationManager.class);
-        PackageManager pm = mock(PackageManager.class);
-        mContext.addMockSystemService(Context.NOTIFICATION_SERVICE, nm);
-        mContext.setMockPackageManager(pm);
-
-        ComponentName testComponent = new ComponentName(getContext().getPackageName(),
-                PluginManagerTest.class.getName());
-        Intent intent = new Intent(PluginManagerImpl.DISABLE_PLUGIN);
-        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),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
-                eq(PackageManager.DONT_KILL_APP));
-    }
-
-    private void resetExceptionHandler() {
-        mPluginExceptionHandler = Thread.getUncaughtExceptionPreHandler();
-        // Set back the real exception handler so the test can crash if it wants to.
-        Thread.setUncaughtExceptionPreHandler(mRealExceptionHandler);
-    }
-
-    @ProvidesInterface(action = TestPlugin.ACTION, version = TestPlugin.VERSION)
-    public static interface TestPlugin extends Plugin {
-        public static final String ACTION = "testAction";
-        public static final int VERSION = 1;
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/VersionInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/VersionInfoTest.java
deleted file mode 100644
index 0b4d9b5..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/VersionInfoTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.VersionInfo.InvalidVersionException;
-import com.android.systemui.plugins.annotations.Requires;
-import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.plugins.qs.DetailAdapter;
-import com.android.systemui.plugins.qs.QS.HeightListener;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-@SmallTest
-public class VersionInfoTest extends SysuiTestCase {
-
-    @Rule
-    public ExpectedException mThrown = ExpectedException.none();
-
-    @Test
-    public void testHasInfo() {
-        VersionInfo info = new VersionInfo();
-        info.addClass(VersionInfoTest.class); // Has no annotations.
-        assertFalse(info.hasVersionInfo());
-
-        info.addClass(OverlayPlugin.class);
-        assertTrue(info.hasVersionInfo());
-    }
-
-    @Test
-    public void testSingleProvides() {
-        VersionInfo overlay = new VersionInfo().addClass(OverlayPlugin.class);
-        VersionInfo impl = new VersionInfo().addClass(OverlayImpl.class);
-        overlay.checkVersion(impl);
-    }
-
-    @Test
-    public void testIncorrectVersion() {
-        VersionInfo overlay = new VersionInfo().addClass(OverlayPlugin.class);
-        VersionInfo impl = new VersionInfo().addClass(OverlayImplIncorrectVersion.class);
-        mThrown.expect(InvalidVersionException.class);
-        overlay.checkVersion(impl);
-    }
-
-    @Test
-    public void testMissingRequired() {
-        VersionInfo overlay = new VersionInfo().addClass(OverlayPlugin.class);
-        VersionInfo impl = new VersionInfo();
-        mThrown.expect(InvalidVersionException.class);
-        overlay.checkVersion(impl);
-    }
-
-    @Test
-    public void testMissingDependencies() {
-        VersionInfo overlay = new VersionInfo().addClass(QS.class);
-        VersionInfo impl = new VersionInfo().addClass(QSImplNoDeps.class);
-        mThrown.expect(InvalidVersionException.class);
-        overlay.checkVersion(impl);
-    }
-
-    @Test
-    public void testHasDependencies() {
-        VersionInfo overlay = new VersionInfo().addClass(QS.class);
-        VersionInfo impl = new VersionInfo().addClass(QSImpl.class);
-        overlay.checkVersion(impl);
-    }
-
-    @Requires(target = OverlayPlugin.class, version = OverlayPlugin.VERSION)
-    public static class OverlayImpl {
-    }
-
-    @Requires(target = OverlayPlugin.class, version = 0)
-    public static class OverlayImplIncorrectVersion {
-    }
-
-    @Requires(target = QS.class, version = QS.VERSION)
-    public static class QSImplNoDeps {
-    }
-
-    @Requires(target = QS.class, version = QS.VERSION)
-    @Requires(target = HeightListener.class, version = HeightListener.VERSION)
-    @Requires(target = DetailAdapter.class, version = DetailAdapter.VERSION)
-    public static class QSImpl {
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index a9d49f9..b44630a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -65,10 +65,12 @@
     private static final long ONE_HOUR_MILLIS = Duration.ofHours(1).toMillis();
     public static final int BELOW_WARNING_BUCKET = -1;
     public static final long BELOW_HYBRID_THRESHOLD = TimeUnit.HOURS.toMillis(2);
+    public static final long BELOW_SEVERE_HYBRID_THRESHOLD = TimeUnit.MINUTES.toMillis(30);
     public static final long ABOVE_HYBRID_THRESHOLD = TimeUnit.HOURS.toMillis(4);
     private static final long ABOVE_CHARGE_CYCLE_THRESHOLD = Duration.ofHours(8).toMillis();
     private static final int OLD_BATTERY_LEVEL_NINE = 9;
     private static final int OLD_BATTERY_LEVEL_10 = 10;
+    private static final long VERY_BELOW_SEVERE_HYBRID_THRESHOLD = TimeUnit.MINUTES.toMillis(15);
     private HardwarePropertiesManager mHardProps;
     private WarningsUI mMockWarnings;
     private PowerUI mPowerUI;
@@ -467,6 +469,35 @@
     }
 
     @Test
+    public void testSevereWarning_countsAsLowAndSevere_WarningOnlyShownOnce() {
+        mPowerUI.start();
+        when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
+        when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
+        when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
+        when(mEnhancedEstimates.getEstimate())
+                .thenReturn(new Estimate(BELOW_SEVERE_HYBRID_THRESHOLD, true));
+        mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
+
+        // reduce battery level to handle time based trigger -> level trigger interactions
+        mPowerUI.mBatteryLevel = 5;
+        boolean shouldShow =
+                mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
+                        ABOVE_WARNING_BUCKET, BELOW_SEVERE_HYBRID_THRESHOLD,
+                        POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
+        assertTrue(shouldShow);
+
+        // actually run the end to end since it handles changing the internal state.
+        mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_10, UNPLUGGED, UNPLUGGED,
+                ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
+
+        shouldShow =
+                mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
+                        ABOVE_WARNING_BUCKET, VERY_BELOW_SEVERE_HYBRID_THRESHOLD,
+                        POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
+        assertFalse(shouldShow);
+    }
+
+    @Test
     public void testMaybeShowBatteryWarning_onlyQueriesEstimateOnBatteryLevelChangeOrNull() {
         mPowerUI.start();
         Estimate estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 85cdfcc..12a122a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -14,8 +14,12 @@
 
 package com.android.systemui.qs;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -23,15 +27,21 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.plugins.qs.QSTileView;
 import com.android.systemui.qs.customize.QSCustomizer;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.Collections;
 
@@ -41,19 +51,37 @@
 public class QSPanelTest extends SysuiTestCase {
 
     private MetricsLogger mMetricsLogger;
+    private TestableLooper mTestableLooper;
     private QSPanel mQsPanel;
+    @Mock
     private QSTileHost mHost;
+    @Mock
     private QSCustomizer mCustomizer;
+    @Mock
+    private QSTile dndTile;
+    private ViewGroup mParentView;
+    @Mock
+    private QSDetail.Callback mCallback;
 
     @Before
     public void setup() throws Exception {
-        TestableLooper.get(this).runWithLooper(() -> {
+        MockitoAnnotations.initMocks(this);
+
+        mTestableLooper = TestableLooper.get(this);
+        mTestableLooper.runWithLooper(() -> {
             mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
             mQsPanel = new QSPanel(mContext, null);
-            mHost = mock(QSTileHost.class);
+            // Provides a parent with non-zero size for QSPanel
+            mParentView = new FrameLayout(mContext);
+            mParentView.addView(mQsPanel);
+
+            when(dndTile.getTileSpec()).thenReturn("dnd");
             when(mHost.getTiles()).thenReturn(Collections.emptyList());
-            mCustomizer = mock(QSCustomizer.class);
+            when(mHost.createTileView(any(), anyBoolean())).thenReturn(mock(QSTileView.class));
+
             mQsPanel.setHost(mHost, mCustomizer);
+            mQsPanel.addTile(dndTile, true);
+            mQsPanel.setCallback(mCallback);
         });
     }
 
@@ -64,4 +92,31 @@
         mQsPanel.setExpanded(false);
         verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false));
     }
+
+    @Test
+    public void testOpenDetailsWithExistingTile_NoException() {
+        mTestableLooper.processAllMessages();
+        mQsPanel.openDetails("dnd");
+        mTestableLooper.processAllMessages();
+
+        verify(mCallback).onShowingDetail(any(), anyInt(), anyInt());
+    }
+
+/*    @Test
+    public void testOpenDetailsWithNullParameter_NoException() {
+        mTestableLooper.processAllMessages();
+        mQsPanel.openDetails(null);
+        mTestableLooper.processAllMessages();
+
+        verify(mCallback, never()).onShowingDetail(any(), anyInt(), anyInt());
+    }*/
+
+    @Test
+    public void testOpenDetailsWithNonExistingTile_NoException() {
+        mTestableLooper.processAllMessages();
+        mQsPanel.openDetails("invalid-name");
+        mTestableLooper.processAllMessages();
+
+        verify(mCallback, never()).onShowingDetail(any(), anyInt(), anyInt());
+    }
 }
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
new file mode 100644
index 0000000..5bf6040
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceManagerTest.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+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;
+import com.android.systemui.plugins.annotations.Requires;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.HandlerThread;
+import android.os.UserHandle;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PluginInstanceManagerTest extends SysuiTestCase {
+
+    private static final String WHITELISTED_PACKAGE = "com.android.systemui";
+    // Static since the plugin needs to be generated by the PluginInstanceManager using newInstance.
+    private static Plugin sMockPlugin;
+
+    private HandlerThread mHandlerThread;
+    private Context mContextWrapper;
+    private PackageManager mMockPm;
+    private PluginListener mMockListener;
+    private PluginInstanceManager mPluginInstanceManager;
+    private PluginManagerImpl mMockManager;
+    private VersionInfo mMockVersionInfo;
+
+    @Before
+    public void setup() throws Exception {
+        mHandlerThread = new HandlerThread("test_thread");
+        mHandlerThread.start();
+        mContextWrapper = new MyContextWrapper(getContext());
+        mMockPm = mock(PackageManager.class);
+        mMockListener = mock(PluginListener.class);
+        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,
+                mMockManager, true, new String[0]);
+        sMockPlugin = mock(Plugin.class);
+        when(sMockPlugin.getVersion()).thenReturn(1);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mHandlerThread.quit();
+        sMockPlugin = null;
+    }
+
+    @UiThreadTest
+    @Test
+    public void testGetPlugin() throws Exception {
+        setupFakePmQuery();
+        PluginInfo p = mPluginInstanceManager.getPlugin();
+        assertNotNull(p.mPlugin);
+        verify(sMockPlugin).onCreate(any(), any());
+    }
+
+    @Test
+    public void testNoPlugins() throws Exception {
+        when(mMockPm.queryIntentServices(any(), anyInt())).thenReturn(
+                Collections.emptyList());
+        mPluginInstanceManager.loadAll();
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);
+
+        verify(mMockListener, Mockito.never()).onPluginConnected(any(), any());
+    }
+
+    @Test
+    public void testPluginCreate() throws Exception {
+        createPlugin();
+
+        // Verify startup lifecycle
+        verify(sMockPlugin).onCreate(ArgumentCaptor.forClass(Context.class).capture(),
+                ArgumentCaptor.forClass(Context.class).capture());
+        verify(mMockListener).onPluginConnected(any(), any());
+    }
+
+    @Test
+    public void testPluginDestroy() throws Exception {
+        createPlugin(); // Get into valid created state.
+
+        mPluginInstanceManager.destroy();
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);
+
+        // Verify shutdown lifecycle
+        verify(mMockListener).onPluginDisconnected(ArgumentCaptor.forClass(Plugin.class).capture());
+        verify(sMockPlugin).onDestroy();
+    }
+
+    @Test
+    public void testIncorrectVersion() throws Exception {
+        NotificationManager nm = mock(NotificationManager.class);
+        mContext.addMockSystemService(Context.NOTIFICATION_SERVICE, nm);
+        setupFakePmQuery();
+        doThrow(new InvalidVersionException("", false)).when(mMockVersionInfo).checkVersion(any());
+
+        mPluginInstanceManager.loadAll();
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);
+
+        // Plugin shouldn't be connected because it is the wrong version.
+        verify(mMockListener, Mockito.never()).onPluginConnected(any(), any());
+        verify(nm).notifyAsUser(eq(TestPlugin.class.getName()), eq(SystemMessage.NOTE_PLUGIN),
+                any(), eq(UserHandle.ALL));
+    }
+
+    @Test
+    public void testReloadOnChange() throws Exception {
+        createPlugin(); // Get into valid created state.
+
+        mPluginInstanceManager.onPackageChange("com.android.systemui");
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);
+
+        // Verify the old one was destroyed.
+        verify(mMockListener).onPluginDisconnected(ArgumentCaptor.forClass(Plugin.class).capture());
+        verify(sMockPlugin).onDestroy();
+        // Also verify we got a second onCreate.
+        verify(sMockPlugin, Mockito.times(2)).onCreate(
+                ArgumentCaptor.forClass(Context.class).capture(),
+                ArgumentCaptor.forClass(Context.class).capture());
+        verify(mMockListener, Mockito.times(2)).onPluginConnected(any(), any());
+    }
+
+    @Test
+    public void testNonDebuggable() throws Exception {
+        // Create a version that thinks the build is not debuggable.
+        mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
+                mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
+                mMockManager, false, new String[0]);
+        setupFakePmQuery();
+
+        mPluginInstanceManager.loadAll();
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);;
+
+        // Non-debuggable build should receive no plugins.
+        verify(mMockListener, Mockito.never()).onPluginConnected(any(), any());
+    }
+
+    @Test
+    public void testNonDebuggable_whitelist() throws Exception {
+        // Create a version that thinks the build is not debuggable.
+        mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
+                mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
+                mMockManager, false, new String[] {WHITELISTED_PACKAGE});
+        setupFakePmQuery();
+
+        mPluginInstanceManager.loadAll();
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);
+
+        // Verify startup lifecycle
+        verify(sMockPlugin).onCreate(ArgumentCaptor.forClass(Context.class).capture(),
+                ArgumentCaptor.forClass(Context.class).capture());
+        verify(mMockListener).onPluginConnected(any(), any());
+    }
+
+    @Test
+    public void testCheckAndDisable() throws Exception {
+        createPlugin(); // Get into valid created state.
+
+        // Start with an unrelated class.
+        boolean result = mPluginInstanceManager.checkAndDisable(Activity.class.getName());
+        assertFalse(result);
+        verify(mMockPm, Mockito.never()).setComponentEnabledSetting(
+                ArgumentCaptor.forClass(ComponentName.class).capture(),
+                ArgumentCaptor.forClass(int.class).capture(),
+                ArgumentCaptor.forClass(int.class).capture());
+
+        // Now hand it a real class and make sure it disables the plugin.
+        result = mPluginInstanceManager.checkAndDisable(TestPlugin.class.getName());
+        assertTrue(result);
+        verify(mMockPm).setComponentEnabledSetting(
+                ArgumentCaptor.forClass(ComponentName.class).capture(),
+                ArgumentCaptor.forClass(int.class).capture(),
+                ArgumentCaptor.forClass(int.class).capture());
+    }
+
+    @Test
+    public void testDisableAll() throws Exception {
+        createPlugin(); // Get into valid created state.
+
+        mPluginInstanceManager.disableAll();
+
+        verify(mMockPm).setComponentEnabledSetting(
+                ArgumentCaptor.forClass(ComponentName.class).capture(),
+                ArgumentCaptor.forClass(int.class).capture(),
+                ArgumentCaptor.forClass(int.class).capture());
+    }
+
+    private void setupFakePmQuery() throws Exception {
+        List<ResolveInfo> list = new ArrayList<>();
+        ResolveInfo info = new ResolveInfo();
+        info.serviceInfo = mock(ServiceInfo.class);
+        info.serviceInfo.packageName = "com.android.systemui";
+        info.serviceInfo.name = TestPlugin.class.getName();
+        when(info.serviceInfo.loadLabel(any())).thenReturn("Test Plugin");
+        list.add(info);
+        when(mMockPm.queryIntentServices(any(), Mockito.anyInt())).thenReturn(list);
+        when(mMockPm.getServiceInfo(any(), anyInt())).thenReturn(info.serviceInfo);
+
+        when(mMockPm.checkPermission(Mockito.anyString(), Mockito.anyString())).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+
+        ApplicationInfo appInfo = getContext().getApplicationInfo();
+        when(mMockPm.getApplicationInfo(Mockito.anyString(), Mockito.anyInt())).thenReturn(
+                appInfo);
+    }
+
+    private void createPlugin() throws Exception {
+        setupFakePmQuery();
+
+        mPluginInstanceManager.loadAll();
+
+        waitForIdleSync(mPluginInstanceManager.mPluginHandler);
+        waitForIdleSync(mPluginInstanceManager.mMainHandler);
+    }
+
+    // Real context with no registering/unregistering of receivers.
+    private static class MyContextWrapper extends ContextWrapper {
+        public MyContextWrapper(Context base) {
+            super(base);
+        }
+
+        @Override
+        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+            return null;
+        }
+
+        @Override
+        public void unregisterReceiver(BroadcastReceiver receiver) {
+        }
+
+        @Override
+        public void sendBroadcast(Intent intent) {
+            // Do nothing.
+        }
+    }
+
+    // This target class doesn't matter, it just needs to have a Requires to hit the flow where
+    // the mock version info is called.
+    @Requires(target = PluginManagerTest.class, version = 1)
+    public static class TestPlugin implements Plugin {
+        @Override
+        public int getVersion() {
+            return sMockPlugin.getVersion();
+        }
+
+        @Override
+        public void onCreate(Context sysuiContext, Context pluginContext) {
+            sMockPlugin.onCreate(sysuiContext, pluginContext);
+        }
+
+        @Override
+        public void onDestroy() {
+            sMockPlugin.onDestroy();
+        }
+    }
+}
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
new file mode 100644
index 0000000..ff1bc8ab
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.shared.plugins;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+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;
+import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;
+import com.android.systemui.shared.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class PluginManagerTest extends SysuiTestCase {
+
+    private static final String WHITELISTED_PACKAGE = "com.android.systemui";
+
+    private PluginInstanceManagerFactory mMockFactory;
+    private PluginInstanceManager mMockPluginInstance;
+    private PluginManagerImpl mPluginManager;
+    private PluginListener mMockListener;
+    private PackageManager mMockPackageManager;
+
+    private UncaughtExceptionHandler mRealExceptionHandler;
+    private UncaughtExceptionHandler mMockExceptionHandler;
+    private UncaughtExceptionHandler mPluginExceptionHandler;
+
+    @Before
+    public void setup() throws Exception {
+        mDependency.injectTestDependency(Dependency.BG_LOOPER,
+                TestableLooper.get(this).getLooper());
+        mRealExceptionHandler = Thread.getUncaughtExceptionPreHandler();
+        mMockExceptionHandler = mock(UncaughtExceptionHandler.class);
+        mMockFactory = mock(PluginInstanceManagerFactory.class);
+        mMockPluginInstance = mock(PluginInstanceManager.class);
+        when(mMockFactory.createPluginInstanceManager(Mockito.any(), Mockito.any(), Mockito.any(),
+                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);
+    }
+
+    @RunWithLooper(setAsMainLooper = true)
+    @Test
+    public void testOneShot() {
+        Plugin mockPlugin = mock(Plugin.class);
+        when(mMockPluginInstance.getPlugin()).thenReturn(new PluginInfo(null, null, mockPlugin,
+                null, null));
+        Plugin result = mPluginManager.getOneShotPlugin("myAction", TestPlugin.class);
+        assertSame(mockPlugin, result);
+    }
+
+    @Test
+    public void testAddListener() {
+        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
+
+        verify(mMockPluginInstance).loadAll();
+    }
+
+    @Test
+    public void testRemoveListener() {
+        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
+
+        mPluginManager.removePluginListener(mMockListener);
+        verify(mMockPluginInstance).destroy();
+    }
+
+    @Test
+    @RunWithLooper(setAsMainLooper = true)
+    public void testNonDebuggable_noWhitelist() {
+        mPluginManager = new PluginManagerImpl(getContext(), mMockFactory, false,
+                mMockExceptionHandler, new PluginInitializerImpl() {
+            @Override
+            public String[] getWhitelistedPlugins(Context context) {
+                return new String[0];
+            }
+        });
+        resetExceptionHandler();
+
+        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
+        assertNull(mPluginManager.getOneShotPlugin("myPlugin", TestPlugin.class));
+        assertNull(mPluginManager.getClassLoader("myPlugin", WHITELISTED_PACKAGE));
+    }
+
+    @Test
+    @RunWithLooper(setAsMainLooper = true)
+    public void testNonDebuggable_whitelistedPkg() {
+        mPluginManager = new PluginManagerImpl(getContext(), mMockFactory, false,
+                mMockExceptionHandler, new PluginInitializerImpl() {
+            @Override
+            public String[] getWhitelistedPlugins(Context context) {
+                return new String[] {WHITELISTED_PACKAGE};
+            }
+        });
+        resetExceptionHandler();
+
+        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
+        assertNotNull(mPluginManager.getClassLoader("myPlugin", WHITELISTED_PACKAGE));
+        assertNull(mPluginManager.getClassLoader("myPlugin", "com.android.invalidpackage"));
+    }
+
+    @Test
+    public void testExceptionHandler_foundPlugin() {
+        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
+        when(mMockPluginInstance.checkAndDisable(Mockito.any())).thenReturn(true);
+
+        mPluginExceptionHandler.uncaughtException(Thread.currentThread(), new Throwable());
+
+        verify(mMockPluginInstance, Mockito.atLeastOnce()).checkAndDisable(
+                ArgumentCaptor.forClass(String.class).capture());
+        verify(mMockPluginInstance, Mockito.never()).disableAll();
+        verify(mMockExceptionHandler).uncaughtException(
+                ArgumentCaptor.forClass(Thread.class).capture(),
+                ArgumentCaptor.forClass(Throwable.class).capture());
+    }
+
+    @Test
+    public void testExceptionHandler_noFoundPlugin() {
+        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
+        when(mMockPluginInstance.checkAndDisable(Mockito.any())).thenReturn(false);
+
+        mPluginExceptionHandler.uncaughtException(Thread.currentThread(), new Throwable());
+
+        verify(mMockPluginInstance, Mockito.atLeastOnce()).checkAndDisable(
+                ArgumentCaptor.forClass(String.class).capture());
+        verify(mMockPluginInstance).disableAll();
+        verify(mMockExceptionHandler).uncaughtException(
+                ArgumentCaptor.forClass(Thread.class).capture(),
+                ArgumentCaptor.forClass(Throwable.class).capture());
+    }
+
+    @Test
+    public void testDisableIntent() {
+        NotificationManager nm = mock(NotificationManager.class);
+        mContext.addMockSystemService(Context.NOTIFICATION_SERVICE, nm);
+        mContext.setMockPackageManager(mMockPackageManager);
+
+        ComponentName testComponent = new ComponentName(getContext().getPackageName(),
+                PluginManagerTest.class.getName());
+        Intent intent = new Intent(PluginManagerImpl.DISABLE_PLUGIN);
+        intent.setData(Uri.parse("package://" + testComponent.flattenToString()));
+        mPluginManager.onReceive(mContext, intent);
+        verify(nm).cancel(eq(testComponent.getClassName()), eq(SystemMessage.NOTE_PLUGIN));
+        verify(mMockPackageManager).setComponentEnabledSetting(eq(testComponent),
+                eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
+                eq(PackageManager.DONT_KILL_APP));
+    }
+
+    private void resetExceptionHandler() {
+        mPluginExceptionHandler = Thread.getUncaughtExceptionPreHandler();
+        // Set back the real exception handler so the test can crash if it wants to.
+        Thread.setUncaughtExceptionPreHandler(mRealExceptionHandler);
+    }
+
+    @ProvidesInterface(action = TestPlugin.ACTION, version = TestPlugin.VERSION)
+    public static interface TestPlugin extends Plugin {
+        public static final String ACTION = "testAction";
+        public static final int VERSION = 1;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
new file mode 100644
index 0000000..9bad78d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.OverlayPlugin;
+import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException;
+import com.android.systemui.plugins.annotations.Requires;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.plugins.qs.DetailAdapter;
+import com.android.systemui.plugins.qs.QS.HeightListener;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+@SmallTest
+public class VersionInfoTest extends SysuiTestCase {
+
+    @Rule
+    public ExpectedException mThrown = ExpectedException.none();
+
+    @Test
+    public void testHasInfo() {
+        VersionInfo info = new VersionInfo();
+        info.addClass(VersionInfoTest.class); // Has no annotations.
+        assertFalse(info.hasVersionInfo());
+
+        info.addClass(OverlayPlugin.class);
+        assertTrue(info.hasVersionInfo());
+    }
+
+    @Test
+    public void testSingleProvides() {
+        VersionInfo overlay = new VersionInfo().addClass(OverlayPlugin.class);
+        VersionInfo impl = new VersionInfo().addClass(OverlayImpl.class);
+        overlay.checkVersion(impl);
+    }
+
+    @Test
+    public void testIncorrectVersion() {
+        VersionInfo overlay = new VersionInfo().addClass(OverlayPlugin.class);
+        VersionInfo impl = new VersionInfo().addClass(OverlayImplIncorrectVersion.class);
+        mThrown.expect(InvalidVersionException.class);
+        overlay.checkVersion(impl);
+    }
+
+    @Test
+    public void testMissingRequired() {
+        VersionInfo overlay = new VersionInfo().addClass(OverlayPlugin.class);
+        VersionInfo impl = new VersionInfo();
+        mThrown.expect(InvalidVersionException.class);
+        overlay.checkVersion(impl);
+    }
+
+    @Test
+    public void testMissingDependencies() {
+        VersionInfo overlay = new VersionInfo().addClass(QS.class);
+        VersionInfo impl = new VersionInfo().addClass(QSImplNoDeps.class);
+        mThrown.expect(InvalidVersionException.class);
+        overlay.checkVersion(impl);
+    }
+
+    @Test
+    public void testHasDependencies() {
+        VersionInfo overlay = new VersionInfo().addClass(QS.class);
+        VersionInfo impl = new VersionInfo().addClass(QSImpl.class);
+        overlay.checkVersion(impl);
+    }
+
+    @Requires(target = OverlayPlugin.class, version = OverlayPlugin.VERSION)
+    public static class OverlayImpl {
+    }
+
+    @Requires(target = OverlayPlugin.class, version = 0)
+    public static class OverlayImplIncorrectVersion {
+    }
+
+    @Requires(target = QS.class, version = QS.VERSION)
+    public static class QSImplNoDeps {
+    }
+
+    @Requires(target = QS.class, version = QS.VERSION)
+    @Requires(target = HeightListener.class, version = HeightListener.VERSION)
+    @Requires(target = DetailAdapter.class, version = DetailAdapter.VERSION)
+    public static class QSImpl {
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index f21ce27..8b41516 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -56,19 +56,19 @@
     private static final String TEST_PACKAGE_NAME = "test";
     private static final int TEST_UID = 0;
 
-    private static final int TEST_MINIMUM_DISPLAY_TIME = 200;
-    private static final int TEST_AUTO_DISMISS_TIME = 500;
+    protected static final int TEST_MINIMUM_DISPLAY_TIME = 200;
+    protected static final int TEST_AUTO_DISMISS_TIME = 500;
     // Number of notifications to use in tests requiring multiple notifications
     private static final int TEST_NUM_NOTIFICATIONS = 4;
-    private static final int TEST_TIMEOUT_TIME = 10000;
-    private final Runnable TEST_TIMEOUT_RUNNABLE = () -> mTimedOut = true;
+    protected static final int TEST_TIMEOUT_TIME = 10000;
+    protected final Runnable TEST_TIMEOUT_RUNNABLE = () -> mTimedOut = true;
 
     private AlertingNotificationManager mAlertingNotificationManager;
 
     protected NotificationData.Entry mEntry;
     protected Handler mTestHandler;
     private StatusBarNotification mSbn;
-    private boolean mTimedOut = false;
+    protected boolean mTimedOut = false;
 
     @Mock protected ExpandableNotificationRow mRow;
 
@@ -122,7 +122,7 @@
     public void testShowNotification_addsEntry() {
         mAlertingNotificationManager.showNotification(mEntry);
 
-        assertTrue(mAlertingNotificationManager.contains(mEntry.key));
+        assertTrue(mAlertingNotificationManager.isAlerting(mEntry.key));
         assertTrue(mAlertingNotificationManager.hasNotifications());
         assertEquals(mEntry, mAlertingNotificationManager.getEntry(mEntry.key));
     }
@@ -136,7 +136,7 @@
         TestableLooper.get(this).processMessages(1);
 
         assertFalse("Test timed out", mTimedOut);
-        assertFalse(mAlertingNotificationManager.contains(mEntry.key));
+        assertFalse(mAlertingNotificationManager.isAlerting(mEntry.key));
     }
 
     @Test
@@ -146,7 +146,7 @@
         // Try to remove but defer, since the notification has not been shown long enough.
         mAlertingNotificationManager.removeNotification(mEntry.key, false /* releaseImmediately */);
 
-        assertTrue(mAlertingNotificationManager.contains(mEntry.key));
+        assertTrue(mAlertingNotificationManager.isAlerting(mEntry.key));
     }
 
     @Test
@@ -156,7 +156,7 @@
         // Remove forcibly with releaseImmediately = true.
         mAlertingNotificationManager.removeNotification(mEntry.key, true /* releaseImmediately */);
 
-        assertFalse(mAlertingNotificationManager.contains(mEntry.key));
+        assertFalse(mAlertingNotificationManager.isAlerting(mEntry.key));
     }
 
     @Test
@@ -174,10 +174,18 @@
     }
 
     @Test
-    public void testShouldExtendLifetime_notShownLongEnough() {
+    public void testCanRemoveImmediately_notShownLongEnough() {
         mAlertingNotificationManager.showNotification(mEntry);
 
-        // The entry has just been added so the lifetime should be extended
+        // The entry has just been added so we should not remove immediately.
+        assertFalse(mAlertingNotificationManager.canRemoveImmediately(mEntry.key));
+    }
+
+    @Test
+    public void testShouldExtendLifetime() {
+        mAlertingNotificationManager.showNotification(mEntry);
+
+        // While the entry is alerting, it should not be removable.
         assertTrue(mAlertingNotificationManager.shouldExtendLifetime(mEntry));
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java
new file mode 100644
index 0000000..f0344e6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class AmbientPulseManagerTest extends AlertingNotificationManagerTest {
+    @Rule
+    public MockitoRule rule = MockitoJUnit.rule();
+
+    private static final int TEST_EXTENSION_TIME = 500;
+    private AmbientPulseManager mAmbientPulseManager;
+    private boolean mLivesPastNormalTime;
+
+    protected AlertingNotificationManager createAlertingNotificationManager() {
+        return mAmbientPulseManager;
+    }
+
+    @Before
+    public void setUp() {
+        mAmbientPulseManager = new AmbientPulseManager(mContext);
+        mAmbientPulseManager.mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
+        mAmbientPulseManager.mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
+        mAmbientPulseManager.mExtensionTime = TEST_EXTENSION_TIME;
+        super.setUp();
+        mAmbientPulseManager.mHandler = mTestHandler;
+    }
+
+    @Test
+    public void testExtendPulse() {
+        mAmbientPulseManager.showNotification(mEntry);
+        Runnable pastNormalTimeRunnable =
+                () -> mLivesPastNormalTime = mAmbientPulseManager.isAlerting(mEntry.key);
+        mTestHandler.postDelayed(pastNormalTimeRunnable,
+                mAmbientPulseManager.mAutoDismissNotificationDecay +
+                        mAmbientPulseManager.mExtensionTime / 2);
+        mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
+
+        mAmbientPulseManager.extendPulse();
+
+        // Wait for normal time runnable and extended remove runnable and process them on arrival.
+        TestableLooper.get(this).processMessages(2);
+
+        assertFalse("Test timed out", mTimedOut);
+        assertTrue("Pulse was not extended", mLivesPastNormalTime);
+        assertFalse(mAmbientPulseManager.isAlerting(mEntry.key));
+    }
+}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
index 09c1931..da59450 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
@@ -79,13 +79,14 @@
                 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(
-                Dependency.get(NotificationGroupManager.class));
+        when(mPresenter.getGroupManager()).thenReturn(groupManager);
 
         entryManager.setUpWithPresenter(mPresenter, mListContainer, mEntryManagerCallback,
                 mHeadsUpManager);
+        groupManager.setHeadsUpManager(mHeadsUpManager);
         gutsManager.setUpWithPresenter(mPresenter, mListContainer, mCheckSaveListener,
                 mOnClickListener);
         notificationLogger.setUpWithEntryManager(entryManager, mListContainer);
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 a7758a6..515c109 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -40,8 +40,11 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import android.util.Log;
 import com.android.systemui.SysuiTestCase;
+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.google.android.collect.Lists;
@@ -61,7 +64,9 @@
 
     // Dependency mocks:
     @Mock private NotificationEntryManager mEntryManager;
+    @Mock private NotificationData mNotificationData;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
+    @Mock private StatusBarKeyguardViewManager mKeyguardViewManager;
 
     private int mCurrentUserId;
     private TestNotificationLockscreenUserManager mLockscreenUserManager;
@@ -79,9 +84,11 @@
         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);
 
         mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext);
         mLockscreenUserManager.setUpWithPresenter(mPresenter, mEntryManager);
+        mLockscreenUserManager.setKeyguardViewManager(mKeyguardViewManager);
     }
 
     @Test
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 b2170fa..edf29ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -31,6 +31,7 @@
 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.NotificationInflaterTest;
@@ -63,6 +64,7 @@
         mContext = context;
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mHeadsUpManager = new HeadsUpManagerPhone(mContext, null, mGroupManager, null, null);
+        mGroupManager.setHeadsUpManager(mHeadsUpManager);
     }
 
     public ExpandableNotificationRow createRow() throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
new file mode 100644
index 0000000..435ede4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.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.systemui.statusbar.notification;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.RemoteAnimationAdapter;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
+import com.android.systemui.statusbar.phone.StatusBarWindowView;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.stubbing.Answer;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ActivityLaunchAnimatorTest extends SysuiTestCase {
+
+    private ActivityLaunchAnimator mLaunchAnimator;
+    private ActivityLaunchAnimator.Callback mCallback = mock(ActivityLaunchAnimator.Callback.class);
+    private StatusBarWindowView mStatusBarWindowView = mock(StatusBarWindowView.class);
+    private NotificationListContainer mNotificationContainer
+            = mock(NotificationListContainer.class);
+    private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class);
+
+    @Before
+    public void setUp() throws Exception {
+        when(mCallback.areLaunchAnimationsEnabled()).thenReturn(true);
+        mLaunchAnimator = new ActivityLaunchAnimator(
+                mStatusBarWindowView,
+                mCallback,
+                mock(NotificationPanelView.class),
+                mNotificationContainer);
+
+    }
+
+    @Test
+    public void testReturnsNullIfNotEnabled() {
+        when(mCallback.areLaunchAnimationsEnabled()).thenReturn(false);
+        RemoteAnimationAdapter launchAnimation = mLaunchAnimator.getLaunchAnimation(mRow,
+                false /* occluded */);
+        Assert.assertTrue("The LaunchAnimator generated an animation even though animations are "
+                        + "disabled", launchAnimation == null);
+    }
+
+    @Test
+    public void testNotWorkingWhenOccluded() {
+        when(mCallback.areLaunchAnimationsEnabled()).thenReturn(false);
+        RemoteAnimationAdapter launchAnimation = mLaunchAnimator.getLaunchAnimation(mRow,
+                true /* occluded */);
+        Assert.assertTrue("The LaunchAnimator generated an animation even though we're occluded",
+                launchAnimation == null);
+    }
+
+    @Test
+    public void testTimeoutCalled() {
+        RemoteAnimationAdapter launchAnimation = mLaunchAnimator.getLaunchAnimation(mRow,
+                false /* occluded */);
+        Assert.assertTrue("No animation generated", launchAnimation != null);
+        executePostsImmediately(mStatusBarWindowView);
+        mLaunchAnimator.setLaunchResult(ActivityManager.START_SUCCESS,
+                true /* wasIntentActivity */);
+        verify(mCallback).onExpandAnimationTimedOut();
+    }
+
+    private void executePostsImmediately(View view) {
+        doAnswer((i) -> {
+            Runnable run = i.getArgument(0);
+            run.run();
+            return null;
+        }).when(view).post(any());
+        doAnswer((i) -> {
+            Runnable run = i.getArgument(0);
+            run.run();
+            return null;
+        }).when(view).postDelayed(any(), anyLong());
+    }
+}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index c236fbe..ca968a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -158,6 +158,11 @@
         PollingCheck.waitFor(1000,
                 () -> VISIBLE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility());
     }
+    private void ensureNoUndoButton() {
+        PollingCheck.waitFor(1000,
+                () -> GONE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility()
+                        && !mNotificationInfo.isAnimating());
+    }
     private void waitForStopButton() {
         PollingCheck.waitFor(1000,
                 () -> VISIBLE == mNotificationInfo.findViewById(R.id.prompt).getVisibility());
@@ -583,9 +588,6 @@
                 true /* isUserSentimentNegative */);
 
         mNotificationInfo.findViewById(R.id.block).performClick();
-        waitForUndoButton();
-        mNotificationInfo.handleCloseControls(true /* save */, false /* force */);
-
         mTestableLooper.processAllMessages();
         verify(listener).checkSave(any(Runnable.class), eq(mSbn));
     }
@@ -805,7 +807,7 @@
     }
 
     @Test
-    public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception {
+    public void testBlockDoesNothingIfCheckSaveListenerIsNoOp() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
@@ -813,10 +815,10 @@
                 }, null, null, true, true);
 
         mNotificationInfo.findViewById(R.id.block).performClick();
-        waitForUndoButton();
+        mTestableLooper.processAllMessages();
+        ensureNoUndoButton();
         mNotificationInfo.handleCloseControls(true, false);
 
-        mTestableLooper.processAllMessages();
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
     }
@@ -831,6 +833,10 @@
                 }, null, null, true, false);
 
         mNotificationInfo.findViewById(R.id.block).performClick();
+        mTestableLooper.processAllMessages();
+        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+                eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
+
         waitForUndoButton();
         mNotificationInfo.handleCloseControls(true, false);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index 06265e5..18dd1fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -15,10 +15,15 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doNothing;
 
 import android.app.Notification;
 import android.service.notification.StatusBarNotification;
@@ -27,7 +32,6 @@
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.testing.ViewUtils;
-import android.testing.ViewUtils;
 import android.view.ViewGroup;
 
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -36,6 +40,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
@@ -72,6 +77,7 @@
         row.resetMenu();
     }
 
+
     @Test
     public void testNoAppOpsInSlowSwipe() {
         NotificationMenuRow row = new NotificationMenuRow(mContext);
@@ -86,4 +92,255 @@
         // one for snooze and one for noti blocking
         assertEquals(2, container.getChildCount());
     }
+
+    @Test
+    public void testIsSnappedAndOnSameSide() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+
+        when(row.isMenuVisible()).thenReturn(true);
+        when(row.isMenuSnapped()).thenReturn(true);
+        when(row.isMenuOnLeft()).thenReturn(true);
+        when(row.isMenuSnappedOnLeft()).thenReturn(true);
+
+        assertTrue("Showing on left and on left", row.isSnappedAndOnSameSide());
+
+
+        when(row.isMenuOnLeft()).thenReturn(false);
+        when(row.isMenuSnappedOnLeft()).thenReturn(false);
+        assertTrue("Snapped to right and on right", row.isSnappedAndOnSameSide());
+
+        when(row.isMenuOnLeft()).thenReturn(true);
+        when(row.isMenuSnapped()).thenReturn(false);
+        assertFalse("Snapped to right and on left", row.isSnappedAndOnSameSide());
+
+        when(row.isMenuOnLeft()).thenReturn(true);
+        when(row.isMenuSnappedOnLeft()).thenReturn(true);
+        when(row.isMenuVisible()).thenReturn(false);
+        assertFalse("Snapped to left and on left, but menu not visible",
+                row.isSnappedAndOnSameSide());
+
+        when(row.isMenuVisible()).thenReturn(true);
+        when(row.isMenuSnapped()).thenReturn(false);
+        assertFalse("Snapped to left and on left, but not actually snapped to",
+                row.isSnappedAndOnSameSide());
+    }
+
+    @Test
+    public void testGetMenuSnapTarget() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        when(row.isMenuOnLeft()).thenReturn(true);
+        doReturn(30).when(row).getSpaceForMenu();
+
+        assertEquals("When on left, snap target is space for menu",
+                30, row.getMenuSnapTarget());
+
+        when(row.isMenuOnLeft()).thenReturn(false);
+        assertEquals("When on right, snap target is negative space for menu",
+                -30, row.getMenuSnapTarget());
+    }
+
+    @Test
+    public void testIsSwipedEnoughToShowMenu() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        when(row.isMenuVisible()).thenReturn(true);
+        when(row.isMenuOnLeft()).thenReturn(true);
+        doReturn(40f).when(row).getMinimumSwipeDistance();
+
+        when(row.getTranslation()).thenReturn(30f);
+        assertFalse("on left, translation is less than min", row.isSwipedEnoughToShowMenu());
+
+        when(row.getTranslation()).thenReturn(50f);
+        assertTrue("on left, translation is greater than min", row.isSwipedEnoughToShowMenu());
+
+        when(row.isMenuOnLeft()).thenReturn(false);
+        when(row.getTranslation()).thenReturn(-30f);
+        assertFalse("on right, translation is greater than -min", row.isSwipedEnoughToShowMenu());
+
+        when(row.getTranslation()).thenReturn(-50f);
+        assertTrue("on right, translation is less than -min", row.isSwipedEnoughToShowMenu());
+
+        when(row.isMenuVisible()).thenReturn(false);
+        when(row.getTranslation()).thenReturn(30f);
+        assertFalse("on left, translation greater than min, but not visible",
+                row.isSwipedEnoughToShowMenu());
+    }
+
+    @Test
+    public void testIsWithinSnapMenuThreshold() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        doReturn(30f).when(row).getSnapBackThreshold();
+        doReturn(50f).when(row).getDismissThreshold();
+
+        when(row.isMenuOnLeft()).thenReturn(true);
+        when(row.getTranslation()).thenReturn(40f);
+        assertTrue("When on left, translation is between min and max",
+                row.isWithinSnapMenuThreshold());
+
+        when(row.getTranslation()).thenReturn(20f);
+        assertFalse("When on left, translation is less than min",
+                row.isWithinSnapMenuThreshold());
+
+        when(row.getTranslation()).thenReturn(60f);
+        assertFalse("When on left, translation is greater than max",
+                row.isWithinSnapMenuThreshold());
+
+        when(row.isMenuOnLeft()).thenReturn(false);
+        when(row.getTranslation()).thenReturn(-40f);
+        assertTrue("When on right, translation is between -min and -max",
+                row.isWithinSnapMenuThreshold());
+
+        when(row.getTranslation()).thenReturn(-20f);
+        assertFalse("When on right, translation is greater than -min",
+                row.isWithinSnapMenuThreshold());
+
+        when(row.getTranslation()).thenReturn(-60f);
+        assertFalse("When on right, translation is less than -max",
+                row.isWithinSnapMenuThreshold());
+    }
+
+    @Test
+    public void testShouldSnapBack() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        doReturn(40f).when(row).getSnapBackThreshold();
+        when(row.isMenuVisible()).thenReturn(false);
+        when(row.isMenuOnLeft()).thenReturn(true);
+
+        when(row.getTranslation()).thenReturn(50f);
+        assertFalse("On left, translation greater than minimum target", row.shouldSnapBack());
+
+        when(row.getTranslation()).thenReturn(30f);
+        assertTrue("On left, translation less than minimum target", row.shouldSnapBack());
+
+        when(row.isMenuOnLeft()).thenReturn(false);
+        when(row.getTranslation()).thenReturn(-50f);
+        assertFalse("On right, translation less than minimum target", row.shouldSnapBack());
+
+        when(row.getTranslation()).thenReturn(-30f);
+        assertTrue("On right, translation greater than minimum target", row.shouldSnapBack());
+    }
+
+    @Test
+    public void testCanBeDismissed() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        ExpandableNotificationRow parent = mock(ExpandableNotificationRow.class);
+
+        when(row.getParent()).thenReturn(parent);
+        when(parent.canViewBeDismissed()).thenReturn(true);
+
+        assertTrue("Row can be dismissed if parent can be dismissed", row.canBeDismissed());
+
+        when(parent.canViewBeDismissed()).thenReturn(false);
+        assertFalse("Row cannot be dismissed if parent cannot be dismissed",
+                row.canBeDismissed());
+    }
+
+    @Test
+    public void testIsTowardsMenu() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        when(row.isMenuVisible()).thenReturn(true);
+        when(row.isMenuOnLeft()).thenReturn(true);
+
+        assertTrue("menu on left, movement is negative", row.isTowardsMenu(-30f));
+        assertFalse("menu on left, movement is positive", row.isTowardsMenu(30f));
+        assertTrue("menu on left, movement is 0", row.isTowardsMenu(0f));
+
+        when(row.isMenuOnLeft()).thenReturn(false);
+        assertTrue("menu on right, movement is positive", row.isTowardsMenu(30f));
+        assertFalse("menu on right, movement is negative", row.isTowardsMenu(-30f));
+        assertTrue("menu on right, movement is 0", row.isTowardsMenu(0f));
+
+        when(row.isMenuVisible()).thenReturn(false);
+        assertFalse("menu on left, movement is negative, but menu not visible",
+                row.isTowardsMenu(-30f));
+    }
+
+    @Test
+    public void onSnapBack() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        NotificationMenuRowPlugin.OnMenuEventListener listener = mock(NotificationMenuRowPlugin
+                .OnMenuEventListener.class);
+        row.setMenuClickListener(listener);
+        ExpandableNotificationRow parent = mock(ExpandableNotificationRow.class);
+        when(row.getParent()).thenReturn(parent);
+        doNothing().when(row).cancelDrag();
+
+        row.onSnapOpen();
+
+        assertTrue("before onSnapClosed, row is snapped to", row.isMenuSnapped());
+        assertFalse("before onSnapClosed, row is not snapping", row.isSnapping());
+
+        row.onSnapClosed();
+
+        assertFalse("after onSnapClosed, row is not snapped to", row.isMenuSnapped());
+        assertTrue("after onSnapClosed, row is snapping", row.isSnapping());
+    }
+
+    @Test
+    public void testOnSnap() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        when(row.isMenuOnLeft()).thenReturn(true);
+        NotificationMenuRowPlugin.OnMenuEventListener listener = mock(NotificationMenuRowPlugin
+                .OnMenuEventListener.class);
+        row.setMenuClickListener(listener);
+        ExpandableNotificationRow parent = mock(ExpandableNotificationRow.class);
+        when(row.getParent()).thenReturn(parent);
+
+        assertFalse("before onSnapOpen, row is not snapped to", row.isMenuSnapped());
+        assertFalse("before onSnapOpen, row is not snapped on left", row.isMenuSnappedOnLeft());
+
+        row.onSnapOpen();
+
+        assertTrue("after onSnapOpen, row is snapped to", row.isMenuSnapped());
+        assertTrue("after onSnapOpen, row is snapped on left", row.isMenuSnapped());
+        verify(listener, times(1)).onMenuShown(parent);
+    }
+
+    @Test
+    public void testOnDismiss() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        doNothing().when(row).cancelDrag();
+        row.onSnapOpen();
+
+        assertFalse("before onDismiss, row is not dismissing", row.isDismissing());
+        assertTrue("before onDismiss, row is showing", row.isMenuSnapped());
+
+        row.onDismiss();
+
+        verify(row, times(1)).cancelDrag();
+        assertTrue("after onDismiss, row is dismissing", row.isDismissing());
+        assertFalse("after onDismiss, row is not showing", row.isMenuSnapped());
+    }
+
+    @Test
+    public void testOnDown() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        doNothing().when(row).beginDrag();
+
+        row.onTouchStart();
+
+        verify(row, times(1)).beginDrag();
+    }
+
+    @Test
+    public void testOnUp() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        row.onTouchStart();
+
+        assertTrue("before onTouchEnd, isUserTouching is true", row.isUserTouching());
+
+        row.onTouchEnd();
+
+        assertFalse("after onTouchEnd, isUserTouching is false", row.isUserTouching());
+    }
+
+    @Test
+    public void testIsMenuVisible() {
+        NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
+        row.setMenuAlpha(0);
+
+        assertFalse("when alpha is 0, menu is not visible", row.isMenuVisible());
+
+        row.setMenuAlpha(0.5f);
+        assertTrue("when alpha is .5, menu is visible", row.isMenuVisible());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index 087aa59..2728453 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.stack;
 
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.NotificationHeaderView;
@@ -51,7 +50,7 @@
 
     @Test
     public void testGetMaxAllowedVisibleChildren_ambient() {
-        mGroup.setShowAmbient(true);
+        mGroup.setOnAmbient(true);
         Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
             NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_AMBIENT);
     }
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 1e3d42b..f8b2436 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,8 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -32,14 +34,15 @@
 import android.os.IPowerManager;
 import android.os.Looper;
 import android.os.PowerManager;
+import android.service.dreams.IDreamManager;
 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.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.NotificationPresenter;
@@ -91,7 +94,7 @@
     @Mock private NotificationData mNotificationData;
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private RemoteInputController mRemoteInputController;
-    @Mock private SystemServicesProxy mSystemServicesProxy;
+    @Mock private IDreamManager mDreamManager;
     private PowerManager mPowerManager;
     private TestableNotificationEntryManager mEntryManager;
 
@@ -111,7 +114,7 @@
         mPowerManager = new PowerManager(mContext, powerManagerService,
                 Handler.createAsync(Looper.myLooper()));
 
-        mEntryManager = new TestableNotificationEntryManager(mSystemServicesProxy, mPowerManager,
+        mEntryManager = new TestableNotificationEntryManager(mDreamManager, mPowerManager,
                 mContext);
         mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, null, mHeadsUpManager,
                 mNotificationData);
@@ -314,6 +317,36 @@
         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);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
new file mode 100644
index 0000000..b5f67c0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification.stack;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+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.mockitoSession;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.service.notification.StatusBarNotification;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.MotionEvent;
+
+import com.android.systemui.SwipeHelper;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.NotificationMenuRow;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+
+/**
+ * Tests for {@link NotificationSwipeHelper}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationSwipeHelperTest extends SysuiTestCase {
+
+    private NotificationSwipeHelper mSwipeHelper;
+    private NotificationSwipeHelper.NotificationCallback mCallback;
+    private NotificationMenuRowPlugin.OnMenuEventListener mListener;
+    private View mView;
+    private MotionEvent mEvent;
+    private NotificationMenuRowPlugin mMenuRow;
+    private Handler mHandler;
+    private ExpandableNotificationRow mNotificationRow;
+    private Runnable mFalsingCheck;
+
+    @Rule public MockitoRule mockito = MockitoJUnit.rule();
+
+    @Before
+    @UiThreadTest
+    public void setUp() throws Exception {
+        mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
+        mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
+        mSwipeHelper = spy(new NotificationSwipeHelper(SwipeHelper.X, mCallback, mContext, mListener));
+        mView = mock(View.class);
+        mEvent = mock(MotionEvent.class);
+        mMenuRow = mock(NotificationMenuRowPlugin.class);
+        mNotificationRow = mock(ExpandableNotificationRow.class);
+        mHandler = mock(Handler.class);
+        mFalsingCheck = mock(Runnable.class);
+    }
+
+    @Test
+    public void testSetExposedMenuView() {
+        assertEquals("intialized with null exposed menu view", null,
+                mSwipeHelper.getExposedMenuView());
+        mSwipeHelper.setExposedMenuView(mView);
+        assertEquals("swipe helper has correct exposedMenuView after setExposedMenuView to a view",
+                mView, mSwipeHelper.getExposedMenuView());
+        mSwipeHelper.setExposedMenuView(null);
+        assertEquals("swipe helper has null exposedMenuView after setExposedMenuView to null",
+                null, mSwipeHelper.getExposedMenuView());
+    }
+
+    @Test
+    public void testClearExposedMenuView() {
+        doNothing().when(mSwipeHelper).setExposedMenuView(mView);
+        mSwipeHelper.clearExposedMenuView();
+        verify(mSwipeHelper, times(1)).setExposedMenuView(null);
+    }
+
+    @Test
+    public void testGetTranslatingParentView() {
+        assertEquals("intialized with null translating parent view", null,
+                mSwipeHelper.getTranslatingParentView());
+        mSwipeHelper.setTranslatingParentView(mView);
+        assertEquals("has translating parent view after setTranslatingParentView with a view",
+                mView, mSwipeHelper.getTranslatingParentView());
+    }
+
+    @Test
+    public void testClearTranslatingParentView() {
+        doNothing().when(mSwipeHelper).setTranslatingParentView(null);
+        mSwipeHelper.clearTranslatingParentView();
+        verify(mSwipeHelper, times(1)).setTranslatingParentView(null);
+    }
+
+    @Test
+    public void testSetCurrentMenuRow() {
+        assertEquals("currentMenuRow initializes to null", null,
+                mSwipeHelper.getCurrentMenuRow());
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
+        assertEquals("currentMenuRow set correctly after setCurrentMenuRow", mMenuRow,
+                mSwipeHelper.getCurrentMenuRow());
+        mSwipeHelper.setCurrentMenuRow(null);
+        assertEquals("currentMenuRow set to null after setCurrentMenuRow to null",
+                null, mSwipeHelper.getCurrentMenuRow());
+    }
+
+    @Test
+    public void testClearCurrentMenuRow() {
+        doNothing().when(mSwipeHelper).setCurrentMenuRow(null);
+        mSwipeHelper.clearCurrentMenuRow();
+        verify(mSwipeHelper, times(1)).setCurrentMenuRow(null);
+    }
+
+    @Test
+    public void testOnDownUpdate_ExpandableNotificationRow() {
+        when(mSwipeHelper.getHandler()).thenReturn(mHandler);
+        when(mSwipeHelper.getFalsingCheck()).thenReturn(mFalsingCheck);
+        doNothing().when(mSwipeHelper).resetExposedMenuView(true, false);
+        doNothing().when(mSwipeHelper).clearCurrentMenuRow();
+        doNothing().when(mSwipeHelper).initializeRow(any());
+
+        mSwipeHelper.onDownUpdate(mNotificationRow, mEvent);
+
+        verify(mSwipeHelper, times(1)).clearCurrentMenuRow();
+        verify(mHandler, times(1)).removeCallbacks(mFalsingCheck);
+        verify(mSwipeHelper, times(1)).resetExposedMenuView(true, false);
+        verify(mSwipeHelper, times(1)).initializeRow(mNotificationRow);
+    }
+
+    @Test
+    public void testOnDownUpdate_notExpandableNotificationRow() {
+        when(mSwipeHelper.getHandler()).thenReturn(mHandler);
+        when(mSwipeHelper.getFalsingCheck()).thenReturn(mFalsingCheck);
+        doNothing().when(mSwipeHelper).resetExposedMenuView(true, false);
+        doNothing().when(mSwipeHelper).clearCurrentMenuRow();
+        doNothing().when(mSwipeHelper).initializeRow(any());
+
+        mSwipeHelper.onDownUpdate(mView, mEvent);
+
+        verify(mSwipeHelper, times(1)).clearCurrentMenuRow();
+        verify(mHandler, times(1)).removeCallbacks(mFalsingCheck);
+        verify(mSwipeHelper, times(1)).resetExposedMenuView(true, false);
+        verify(mSwipeHelper, times(0)).initializeRow(any());
+    }
+
+    @Test
+    public void testOnMoveUpdate_menuRow() {
+        when(mSwipeHelper.getCurrentMenuRow()).thenReturn(mMenuRow);
+        when(mSwipeHelper.getHandler()).thenReturn(mHandler);
+        when(mSwipeHelper.getFalsingCheck()).thenReturn(mFalsingCheck);
+
+        mSwipeHelper.onMoveUpdate(mView, mEvent, 0, 10);
+
+        verify(mHandler, times(1)).removeCallbacks(mFalsingCheck);
+        verify(mMenuRow, times(1)).onTouchMove(10);
+    }
+
+    @Test
+    public void testOnMoveUpdate_noMenuRow() {
+        when(mSwipeHelper.getHandler()).thenReturn(mHandler);
+        when(mSwipeHelper.getFalsingCheck()).thenReturn(mFalsingCheck);
+
+        mSwipeHelper.onMoveUpdate(mView, mEvent, 0, 10);
+
+        verify(mHandler, times(1)).removeCallbacks(mFalsingCheck);
+    }
+
+    @Test
+    public void testHandleUpEvent_noMenuRow() {
+        assertFalse("Menu row does not exist",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+    }
+
+    @Test
+    public void testHandleUpEvent_menuRow() {
+        when(mSwipeHelper.getCurrentMenuRow()).thenReturn(mMenuRow);
+        doNothing().when(mSwipeHelper).handleMenuRowSwipe(mEvent, mView, 0, mMenuRow);
+
+        assertTrue("Menu row exists",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+        verify(mMenuRow, times(1)).onTouchEnd();
+        verify(mSwipeHelper, times(1)).handleMenuRowSwipe(mEvent, mView, 0, mMenuRow);
+    }
+
+    @Test
+    public void testDismissChild_notExpanded() {
+        when(mCallback.isExpanded()).thenReturn(false);
+        doNothing().when(mSwipeHelper).superDismissChild(mView, 0, false);
+        doNothing().when(mSwipeHelper).handleMenuCoveredOrDismissed();
+
+        mSwipeHelper.dismissChild(mView, 0, false);
+
+        verify(mSwipeHelper, times(1)).superDismissChild(mView, 0, false);
+        verify(mCallback, times(0)).handleChildViewDismissed(mView);
+        verify(mCallback, times(1)).onDismiss();
+        verify(mSwipeHelper, times(1)).handleMenuCoveredOrDismissed();
+    }
+
+    @Test
+    public void testSnapchild_targetIsZero() {
+        doNothing().when(mSwipeHelper).superSnapChild(mView, 0, 0);
+        mSwipeHelper.snapChild(mView, 0, 0);
+
+        verify(mCallback, times(1)).onDragCancelled(mView);
+        verify(mSwipeHelper, times(1)).superSnapChild(mView, 0, 0);
+        verify(mSwipeHelper, times(1)).handleMenuCoveredOrDismissed();
+    }
+
+
+    @Test
+    public void testSnapchild_targetNotZero() {
+        doNothing().when(mSwipeHelper).superSnapChild(mView, 10, 0);
+        mSwipeHelper.snapChild(mView, 10, 0);
+
+        verify(mCallback, times(1)).onDragCancelled(mView);
+        verify(mSwipeHelper, times(1)).superSnapChild(mView, 10, 0);
+        verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed();
+    }
+
+    @Test
+    public void testSnooze() {
+        StatusBarNotification sbn = mock(StatusBarNotification.class);
+        SnoozeOption snoozeOption = mock(SnoozeOption.class);
+        mSwipeHelper.snooze(sbn, snoozeOption);
+        verify(mCallback, times(1)).onSnooze(sbn, snoozeOption);
+    }
+
+    @Test
+    public void testGetViewTranslationAnimator_notExpandableNotificationRow() {
+        Animator animator = mock(Animator.class);
+        AnimatorUpdateListener listener = mock(AnimatorUpdateListener.class);
+        doReturn(animator).when(mSwipeHelper).superGetViewTranslationAnimator(mView, 0, listener);
+
+        assertEquals("returns the correct animator from super", animator,
+                mSwipeHelper.getViewTranslationAnimator(mView, 0, listener));
+
+        verify(mSwipeHelper, times(1)).superGetViewTranslationAnimator(mView, 0, listener);
+    }
+
+    @Test
+    public void testGetViewTranslationAnimator_expandableNotificationRow() {
+        Animator animator = mock(Animator.class);
+        AnimatorUpdateListener listener = mock(AnimatorUpdateListener.class);
+        doReturn(animator).when(mNotificationRow).getTranslateViewAnimator(0, listener);
+
+        assertEquals("returns the correct animator from super when view is an ENR", animator,
+                mSwipeHelper.getViewTranslationAnimator(mNotificationRow, 0, listener));
+
+        verify(mNotificationRow, times(1)).getTranslateViewAnimator(0, listener);
+    }
+
+    @Test
+    public void testSetTranslation() {
+        mSwipeHelper.setTranslation(mNotificationRow, 0);
+        verify(mNotificationRow, times(1)).setTranslation(0);
+    }
+
+    @Test
+    public void testGetTranslation() {
+        doReturn(30f).when(mNotificationRow).getTranslation();
+
+        assertEquals("Returns getTranslation for the ENR",
+                mSwipeHelper.getTranslation(mNotificationRow), 30f);
+
+        verify(mNotificationRow, times(1)).getTranslation();
+    }
+
+    @Test
+    public void testDismiss() {
+        doNothing().when(mSwipeHelper).dismissChild(mView, 0, true);
+        doReturn(false).when(mSwipeHelper).swipedFastEnough();
+
+        mSwipeHelper.dismiss(mView, 0);
+
+        verify(mSwipeHelper, times(1)).swipedFastEnough();
+        verify(mSwipeHelper, times(1)).dismissChild(mView, 0, true);
+    }
+
+    @Test
+    public void testSnapOpen() {
+        doNothing().when(mSwipeHelper).snapChild(mView, 30, 0);
+
+        mSwipeHelper.snapOpen(mView, 30, 0);
+
+        verify(mSwipeHelper, times(1)).snapChild(mView, 30, 0);
+    }
+
+    @Test
+    public void testSnapClosed() {
+        doNothing().when(mSwipeHelper).snapChild(mView, 0, 0);
+
+        mSwipeHelper.snapClosed(mView, 0);
+
+        verify(mSwipeHelper, times(1)).snapChild(mView, 0, 0);
+    }
+
+    @Test
+    public void testGetMinDismissVelocity() {
+        doReturn(30f).when(mSwipeHelper).getEscapeVelocity();
+
+        assertEquals("Returns getEscapeVelocity", 30f, mSwipeHelper.getMinDismissVelocity());
+    }
+
+    @Test
+    public void onMenuShown_noAntiFalsing() {
+        doNothing().when(mSwipeHelper).setExposedMenuView(mView);
+        doReturn(mView).when(mSwipeHelper).getTranslatingParentView();
+        doReturn(mHandler).when(mSwipeHelper).getHandler();
+        doReturn(false).when(mCallback).isAntiFalsingNeeded();
+        doReturn(mFalsingCheck).when(mSwipeHelper).getFalsingCheck();
+
+        mSwipeHelper.onMenuShown(mView);
+
+        verify(mSwipeHelper, times(1)).setExposedMenuView(mView);
+        verify(mCallback, times(1)).onDragCancelled(mView);
+        verify(mCallback, times(1)).isAntiFalsingNeeded();
+
+        verify(mHandler, times(0)).removeCallbacks(mFalsingCheck);
+        verify(mHandler, times(0)).postDelayed(mFalsingCheck, mSwipeHelper.COVER_MENU_DELAY);
+    }
+
+    @Test
+    public void onMenuShown_antiFalsing() {
+        doNothing().when(mSwipeHelper).setExposedMenuView(mView);
+        doReturn(mView).when(mSwipeHelper).getTranslatingParentView();
+        doReturn(mHandler).when(mSwipeHelper).getHandler();
+        doReturn(true).when(mCallback).isAntiFalsingNeeded();
+        doReturn(mFalsingCheck).when(mSwipeHelper).getFalsingCheck();
+
+        mSwipeHelper.onMenuShown(mView);
+
+        verify(mSwipeHelper, times(1)).setExposedMenuView(mView);
+        verify(mCallback, times(1)).onDragCancelled(mView);
+        verify(mCallback, times(1)).isAntiFalsingNeeded();
+
+        verify(mHandler, times(1)).removeCallbacks(mFalsingCheck);
+        verify(mHandler, times(1)).postDelayed(mFalsingCheck, mSwipeHelper.COVER_MENU_DELAY);
+    }
+
+    @Test
+    public void testResetExposedMenuView_noReset() {
+        doReturn(false).when(mSwipeHelper).shouldResetMenu(false);
+        doNothing().when(mSwipeHelper).clearExposedMenuView();
+
+        mSwipeHelper.resetExposedMenuView(false, false);
+
+        verify(mSwipeHelper, times(1)).shouldResetMenu(false);
+
+        // should not clear exposed menu row
+        verify(mSwipeHelper, times(0)).clearExposedMenuView();
+    }
+
+    @Test
+    public void testResetExposedMenuView_animate() {
+        Animator animator = mock(Animator.class);
+
+        doReturn(true).when(mSwipeHelper).shouldResetMenu(false);
+        doReturn(mNotificationRow).when(mSwipeHelper).getExposedMenuView();
+        doReturn(false).when(mNotificationRow).isRemoved();
+        doReturn(animator).when(mSwipeHelper).getViewTranslationAnimator(mNotificationRow, 0, null);
+        doNothing().when(mSwipeHelper).clearExposedMenuView();
+
+        mSwipeHelper.resetExposedMenuView(true, false);
+
+        verify(mSwipeHelper, times(1)).shouldResetMenu(false);
+
+        // should retrieve and start animator
+        verify(mSwipeHelper, times(1)).getViewTranslationAnimator(mNotificationRow, 0, null);
+        verify(animator, times(1)).start();
+
+        // should not reset translation on row directly
+        verify(mNotificationRow, times(0)).resetTranslation();
+
+        // should clear exposed menu row
+        verify(mSwipeHelper, times(1)).clearExposedMenuView();
+    }
+
+
+    @Test
+    public void testResetExposedMenuView_noAnimate() {
+        Animator animator = mock(Animator.class);
+
+        doReturn(true).when(mSwipeHelper).shouldResetMenu(false);
+        doReturn(mNotificationRow).when(mSwipeHelper).getExposedMenuView();
+        doReturn(false).when(mNotificationRow).isRemoved();
+        doReturn(animator).when(mSwipeHelper).getViewTranslationAnimator(mNotificationRow, 0, null);
+        doNothing().when(mSwipeHelper).clearExposedMenuView();
+
+        mSwipeHelper.resetExposedMenuView(false, false);
+
+        verify(mSwipeHelper, times(1)).shouldResetMenu(false);
+
+        // should not retrieve and start animator
+        verify(mSwipeHelper, times(0)).getViewTranslationAnimator(mNotificationRow, 0, null);
+        verify(animator, times(0)).start();
+
+        // should reset translation on row directly
+        verify(mNotificationRow, times(1)).resetTranslation();
+
+        // should clear exposed menu row
+        verify(mSwipeHelper, times(1)).clearExposedMenuView();
+    }
+
+    @Test
+    public void testIsTouchInView() {
+        assertEquals("returns false when view is null", false,
+                NotificationSwipeHelper.isTouchInView(mEvent, null));
+
+        doReturn(5f).when(mEvent).getRawX();
+        doReturn(10f).when(mEvent).getRawY();
+
+        doReturn(20).when(mView).getWidth();
+        doReturn(20).when(mView).getHeight();
+
+        Answer answer = (Answer) invocation -> {
+            int[] arr = invocation.getArgument(0);
+            arr[0] = 0;
+            arr[1] = 0;
+            return null;
+        };
+        doAnswer(answer).when(mView).getLocationOnScreen(any());
+
+        assertTrue("Touch is within the view",
+                mSwipeHelper.isTouchInView(mEvent, mView));
+
+        doReturn(50f).when(mEvent).getRawX();
+
+        assertFalse("Touch is not within the view",
+                mSwipeHelper.isTouchInView(mEvent, mView));
+    }
+
+    @Test
+    public void testIsTouchInView_expandable() {
+        assertEquals("returns false when view is null", false,
+                NotificationSwipeHelper.isTouchInView(mEvent, null));
+
+        doReturn(5f).when(mEvent).getRawX();
+        doReturn(10f).when(mEvent).getRawY();
+
+        doReturn(20).when(mNotificationRow).getWidth();
+        doReturn(20).when(mNotificationRow).getActualHeight();
+
+        Answer answer = (Answer) invocation -> {
+            int[] arr = invocation.getArgument(0);
+            arr[0] = 0;
+            arr[1] = 0;
+            return null;
+        };
+        doAnswer(answer).when(mNotificationRow).getLocationOnScreen(any());
+
+        assertTrue("Touch is within the view",
+                mSwipeHelper.isTouchInView(mEvent, mNotificationRow));
+
+        doReturn(50f).when(mEvent).getRawX();
+
+        assertFalse("Touch is not within the view",
+                mSwipeHelper.isTouchInView(mEvent, mNotificationRow));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index a81d17f..1070795 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -82,28 +82,26 @@
         // Remove should succeed because the notification is swiped out
         mHeadsUpManager.removeNotification(mEntry.key, false /* releaseImmediately */);
 
-        assertFalse(mHeadsUpManager.contains(mEntry.key));
+        assertFalse(mHeadsUpManager.isAlerting(mEntry.key));
     }
 
     @Test
-    public void testShouldExtendLifetime_swipedOut() {
+    public void testCanRemoveImmediately_swipedOut() {
         mHeadsUpManager.showNotification(mEntry);
         mHeadsUpManager.addSwipedOutNotification(mEntry.key);
 
-        // Notification is swiped so its lifetime should not be extended even if it hasn't been
-        // shown long enough
-        assertFalse(mHeadsUpManager.shouldExtendLifetime(mEntry));
+        // Notification is swiped so it can be immediately removed.
+        assertTrue(mHeadsUpManager.canRemoveImmediately(mEntry.key));
     }
 
     @Test
-    public void testShouldExtendLifetime_notTopEntry() {
+    public void testCanRemoveImmediately_notTopEntry() {
         NotificationData.Entry laterEntry = new NotificationData.Entry(createNewNotification(1));
         laterEntry.row = mRow;
         mHeadsUpManager.showNotification(mEntry);
         mHeadsUpManager.showNotification(laterEntry);
 
-        // Notification is "behind" a higher priority notification so we have no reason to keep
-        // its lifetime extended
-        assertFalse(mHeadsUpManager.shouldExtendLifetime(mEntry));
+        // Notification is "behind" a higher priority notification so we can remove it immediately.
+        assertTrue(mHeadsUpManager.canRemoveImmediately(mEntry.key));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
new file mode 100644
index 0000000..c792459
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.doReturn;
+
+import android.graphics.drawable.Drawable;
+import android.support.test.filters.SmallTest;
+import android.view.View;
+import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.SysuiTestCase;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.support.test.runner.AndroidJUnit4;
+
+/** atest NavigationBarContextTest */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NavigationBarContextTest extends SysuiTestCase {
+    private static final int GROUP_ID = 1;
+    private static final int BUTTON_0_ID = GROUP_ID + 1;
+    private static final int BUTTON_1_ID = GROUP_ID + 2;
+    private static final int BUTTON_2_ID = GROUP_ID + 3;
+
+    private static final float TEST_DARK_INTENSITY = 0.6f;
+    private static final float DARK_INTENSITY_ERR = 0.0002f;
+    private static final int ICON_RES_ID = 1;
+
+    private ContextualButtonGroup mGroup;
+    private ContextualButton mBtn0;
+    private ContextualButton mBtn1;
+    private ContextualButton mBtn2;
+
+    @Before
+    public void setup() {
+        mGroup = new ContextualButtonGroup(GROUP_ID);
+        mBtn0 = new ContextualButton(BUTTON_0_ID, ICON_RES_ID);
+        mBtn1 = new ContextualButton(BUTTON_1_ID, ICON_RES_ID);
+        mBtn2 = new ContextualButton(BUTTON_2_ID, ICON_RES_ID);
+
+        // Order of adding buttons to group determines the priority, ascending priority order
+        mGroup.addButton(mBtn0);
+        mGroup.addButton(mBtn1);
+        mGroup.addButton(mBtn2);
+    }
+
+    @Test
+    public void testAddGetContextButtons() throws Exception {
+        assertEquals(mBtn0, mGroup.getContextButton(BUTTON_0_ID));
+        assertEquals(mBtn1, mGroup.getContextButton(BUTTON_1_ID));
+        assertEquals(mBtn2, mGroup.getContextButton(BUTTON_2_ID));
+    }
+
+    @Test
+    public void testSetButtonVisibility() throws Exception {
+        assertFalse("By default the group should be invisible.", mGroup.isVisible());
+
+        // Set button 1 to be visible, make sure it is the only visible button
+        showButton(mBtn1);
+        assertFalse(mBtn0.isVisible());
+        assertTrue(mBtn1.isVisible());
+        assertFalse(mBtn2.isVisible());
+
+        // Hide button 1 and make sure the group is also invisible
+        assertNotEquals(mGroup.setButtonVisiblity(BUTTON_1_ID, false /* visible */), View.VISIBLE);
+        assertFalse("No buttons are visible, group should also be hidden", mGroup.isVisible());
+        assertNull("No buttons should be visible", mGroup.getVisibleContextButton());
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testSetButtonVisibilityUnaddedButton() throws Exception {
+        int id = mBtn2.getId() + 1;
+        mGroup.setButtonVisiblity(id, true /* visible */);
+        fail("Did not throw when setting a button with an invalid id");
+    }
+
+    @Test
+    public void testSetHigherPriorityButton() throws Exception {
+        // Show button 0
+        showButton(mBtn0);
+
+        // Show button 1
+        showButton(mBtn1);
+        assertTrue("Button 0 should be visible behind",
+                mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+
+        // Show button 2
+        showButton(mBtn2);
+        assertTrue("Button 1 should be visible behind",
+                mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
+        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
+        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
+
+        // Hide button 2
+        assertNotEquals(mGroup.setButtonVisiblity(BUTTON_2_ID, false /* visible */), View.VISIBLE);
+        assertEquals("Hiding button 2 should show button 1", mBtn1,
+                mGroup.getVisibleContextButton());
+
+        // Hide button 1
+        assertNotEquals(mGroup.setButtonVisiblity(BUTTON_1_ID, false /* visible */), View.VISIBLE);
+        assertEquals("Hiding button 1 should show button 0", mBtn0,
+                mGroup.getVisibleContextButton());
+
+        // Hide button 0, all buttons are now invisible
+        assertNotEquals(mGroup.setButtonVisiblity(BUTTON_0_ID, false /* visible */), View.VISIBLE);
+        assertFalse("No buttons are visible, group should also be invisible", mGroup.isVisible());
+        assertNull(mGroup.getVisibleContextButton());
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
+    }
+
+    @Test
+    public void testSetLowerPriorityButton() throws Exception {
+        // Show button 2
+        showButton(mBtn2);
+
+        // Show button 1
+        assertNotEquals(mGroup.setButtonVisiblity(BUTTON_1_ID, true /* visible */), View.VISIBLE);
+        assertTrue("Showing button 1 lower priority should be hidden but visible underneath",
+                mGroup.isButtonVisibleWithinGroup(BUTTON_1_ID));
+        assertFalse(mBtn0.isVisible());
+        assertFalse(mBtn1.isVisible());
+        assertTrue(mBtn2.isVisible());
+
+        // Hide button 1
+        assertNotEquals(mGroup.setButtonVisiblity(BUTTON_1_ID, false /* visible */), View.VISIBLE);
+        assertFalse("Hiding button 1 with lower priority hides itself underneath",
+                mGroup.isButtonVisibleWithinGroup(BUTTON_1_ID));
+        assertTrue("A button still visible, group should also be visible", mGroup.isVisible());
+        assertEquals(mBtn2, mGroup.getVisibleContextButton());
+    }
+
+    @Test
+    public void testSetSamePriorityButton() throws Exception {
+        // Show button 1
+        showButton(mBtn1);
+
+        // Show button 1 again
+        showButton(mBtn1);
+
+        // The original button should still be visible
+        assertEquals(mBtn1, mGroup.getVisibleContextButton());
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
+    }
+
+    @Test
+    public void testUpdateIconsDarkIntensity() throws Exception {
+        final int unusedColor = 0;
+        final Drawable d = mock(Drawable.class);
+        final ContextualButton button = spy(mBtn0);
+        final KeyButtonDrawable kbd1 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor));
+        final KeyButtonDrawable kbd2 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor));
+        kbd1.setDarkIntensity(TEST_DARK_INTENSITY);
+        kbd2.setDarkIntensity(0f);
+
+        // Update icon returns the drawable intensity to half
+        doReturn(kbd1).when(button).getNewDrawable();
+        button.updateIcon();
+        assertEquals(TEST_DARK_INTENSITY, kbd1.getDarkIntensity(), DARK_INTENSITY_ERR);
+
+        // Return old dark intensity on new drawable after update icon
+        doReturn(kbd2).when(button).getNewDrawable();
+        button.updateIcon();
+        assertEquals(TEST_DARK_INTENSITY, kbd2.getDarkIntensity(), DARK_INTENSITY_ERR);
+    }
+
+    private void showButton(ContextualButton button) {
+        assertEquals(View.VISIBLE, mGroup.setButtonVisiblity(button.getId(), true /* visible */));
+        assertTrue("After set a button visible, group should also be visible", mGroup.isVisible());
+        assertEquals(button, mGroup.getVisibleContextButton());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
index 6a3c8a8..464f74b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
@@ -36,6 +36,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.NotificationGroupManager.OnGroupChangeListener;
@@ -60,15 +61,23 @@
     private static final String TEST_CHANNEL_ID = "test_channel";
     private static final String TEST_GROUP_ID = "test_group";
     private static final String TEST_PACKAGE_NAME = "test_pkg";
-    private NotificationGroupManager mGroupManager = new NotificationGroupManager();
+    private NotificationGroupManager mGroupManager;
     private int mId = 0;
 
     @Mock HeadsUpManager mHeadsUpManager;
+    @Mock AmbientPulseManager mAmbientPulseManager;
 
     @Before
     public void setup() {
-         mGroupManager.setHeadsUpManager(mHeadsUpManager);
-         mGroupManager.setOnGroupChangeListener(mock(OnGroupChangeListener.class));
+        mDependency.injectTestDependency(AmbientPulseManager.class, mAmbientPulseManager);
+
+        initializeGroupManager();
+    }
+
+    private void initializeGroupManager() {
+        mGroupManager = new NotificationGroupManager();
+        mGroupManager.setHeadsUpManager(mHeadsUpManager);
+        mGroupManager.setOnGroupChangeListener(mock(OnGroupChangeListener.class));
     }
 
     @Test
@@ -141,8 +150,7 @@
         mGroupManager.onEntryAdded(summaryEntry);
         mGroupManager.onEntryAdded(childEntry);
         mGroupManager.onEntryAdded(createChildNotification());
-        when(childEntry.row.isHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.contains(childEntry.key)).thenReturn(true);
+        when(mHeadsUpManager.isAlerting(childEntry.key)).thenReturn(true);
 
         mGroupManager.onHeadsUpStateChanged(childEntry, true);
 
@@ -154,17 +162,35 @@
     }
 
     @Test
+    public void testAmbientPulseEntryIsIsolated() {
+        mGroupManager.setDozing(true);
+        NotificationData.Entry childEntry = createChildNotification();
+        NotificationData.Entry summaryEntry = createSummaryNotification();
+        mGroupManager.onEntryAdded(summaryEntry);
+        mGroupManager.onEntryAdded(childEntry);
+        mGroupManager.onEntryAdded(createChildNotification());
+        when(mAmbientPulseManager.isAlerting(childEntry.key)).thenReturn(true);
+
+        mGroupManager.onAmbientStateChanged(childEntry, true);
+
+        // Child entries that are heads upped should be considered separate groups visually even if
+        // they are the same group logically
+        assertEquals(childEntry.row, mGroupManager.getGroupSummary(childEntry.notification));
+        assertEquals(summaryEntry.row,
+                mGroupManager.getLogicalGroupSummary(childEntry.notification));
+    }
+
+    @Test
     public void testSuppressedSummaryHeadsUpTransfersToChild() {
         NotificationData.Entry summaryEntry = createSummaryNotification();
-        when(summaryEntry.row.isHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.contains(summaryEntry.key)).thenReturn(true);
+        when(mHeadsUpManager.isAlerting(summaryEntry.key)).thenReturn(true);
         NotificationData.Entry childEntry = createChildNotification();
 
-        // Summary will be suppressed because there is only one child
+        // Summary will be suppressed because there is only one child.
         mGroupManager.onEntryAdded(summaryEntry);
         mGroupManager.onEntryAdded(childEntry);
 
-        // A suppressed summary should transfer its heads up state to the child
+        // A suppressed summary should transfer its heads up state to the child.
         verify(mHeadsUpManager, never()).showNotification(summaryEntry);
         verify(mHeadsUpManager).showNotification(childEntry);
     }
@@ -175,24 +201,64 @@
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
         NotificationData.Entry summaryEntry =
                 createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
-        when(summaryEntry.row.isHeadsUp()).thenReturn(true);
         NotificationData.Entry childEntry =
                 createChildNotification(Notification.GROUP_ALERT_SUMMARY);
         NotificationData.Entry childEntry2 =
                 createChildNotification(Notification.GROUP_ALERT_SUMMARY);
+        mHeadsUpManager.showNotification(summaryEntry);
         // Trigger a transfer of heads up state from summary to child.
         mGroupManager.onEntryAdded(summaryEntry);
         mGroupManager.onEntryAdded(childEntry);
-        when(summaryEntry.row.isHeadsUp()).thenReturn(false);
-        when(childEntry.row.isHeadsUp()).thenReturn(true);
 
         // Add second child notification so that summary is no longer suppressed.
         mGroupManager.onEntryAdded(childEntry2);
 
         // The heads up state should transfer back to the summary as there is now more than one
         // child and the summary should no longer be suppressed.
-        assertTrue(mHeadsUpManager.contains(summaryEntry.key));
-        assertFalse(mHeadsUpManager.contains(childEntry.key));
+        assertTrue(mHeadsUpManager.isAlerting(summaryEntry.key));
+        assertFalse(mHeadsUpManager.isAlerting(childEntry.key));
+    }
+
+    @Test
+    public void testSuppressedSummaryAmbientPulseTransfersToChild() {
+        mGroupManager.setDozing(true);
+        NotificationData.Entry summaryEntry = createSummaryNotification();
+        when(mAmbientPulseManager.isAlerting(summaryEntry.key)).thenReturn(true);
+        NotificationData.Entry childEntry = createChildNotification();
+
+        // Summary will be suppressed because there is only one child.
+        mGroupManager.onEntryAdded(summaryEntry);
+        mGroupManager.onEntryAdded(childEntry);
+
+        // A suppressed summary should transfer its ambient state to the child.
+        verify(mAmbientPulseManager, never()).showNotification(summaryEntry);
+        verify(mAmbientPulseManager).showNotification(childEntry);
+    }
+
+    @Test
+    public void testSuppressedSummaryAmbientPulseTransfersToChildButBackAgain() {
+        mGroupManager.setDozing(true);
+        mAmbientPulseManager = new AmbientPulseManager(mContext);
+        mDependency.injectTestDependency(AmbientPulseManager.class, mAmbientPulseManager);
+        initializeGroupManager();
+        NotificationData.Entry summaryEntry =
+                createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
+        NotificationData.Entry childEntry =
+                createChildNotification(Notification.GROUP_ALERT_SUMMARY);
+        NotificationData.Entry childEntry2 =
+                createChildNotification(Notification.GROUP_ALERT_SUMMARY);
+        mAmbientPulseManager.showNotification(summaryEntry);
+        // Trigger a transfer of ambient state from summary to child.
+        mGroupManager.onEntryAdded(summaryEntry);
+        mGroupManager.onEntryAdded(childEntry);
+
+        // Add second child notification so that summary is no longer suppressed.
+        mGroupManager.onEntryAdded(childEntry2);
+
+        // The ambient state should transfer back to the summary as there is now more than one
+        // child and the summary should no longer be suppressed.
+        assertTrue(mAmbientPulseManager.isAlerting(summaryEntry.key));
+        assertFalse(mAmbientPulseManager.isAlerting(childEntry.key));
     }
 
     private NotificationData.Entry createSummaryNotification() {
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 cbba251..da93327 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
@@ -50,6 +50,7 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
 import android.support.test.filters.SmallTest;
 import android.support.test.metricshelper.MetricsAsserts;
@@ -119,9 +120,9 @@
     @Mock private KeyguardIndicationController mKeyguardIndicationController;
     @Mock private NotificationStackScrollLayout mStackScroller;
     @Mock private HeadsUpManagerPhone mHeadsUpManager;
-    @Mock private SystemServicesProxy mSystemServicesProxy;
     @Mock private NotificationPanelView mNotificationPanelView;
     @Mock private IStatusBarService mBarService;
+    @Mock private IDreamManager mDreamManager;
     @Mock private ScrimController mScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private BiometricUnlockController mBiometricUnlockController;
@@ -194,8 +195,7 @@
             return null;
         }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
 
-        mEntryManager = new TestableNotificationEntryManager(mSystemServicesProxy, mPowerManager,
-                mContext);
+        mEntryManager = new TestableNotificationEntryManager(mDreamManager, mPowerManager, mContext);
         when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
         mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
                 mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
@@ -358,12 +358,12 @@
     }
 
     @Test
-    public void testShouldPeek_nonSuppressedGroupSummary() {
+    public void testShouldHeadsUp_nonSuppressedGroupSummary() throws Exception {
         when(mPowerManager.isScreenOn()).thenReturn(true);
         when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
         when(mNotificationData.shouldSuppressStatusBar(any())).thenReturn(false);
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
-        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
 
         Notification n = new Notification.Builder(getContext(), "a")
@@ -375,16 +375,16 @@
                 UserHandle.of(0), null, 0);
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
 
-        assertTrue(mEntryManager.shouldPeek(entry, sbn));
+        assertTrue(mEntryManager.shouldHeadsUp(entry));
     }
 
     @Test
-    public void testShouldPeek_suppressedGroupSummary() {
+    public void testShouldHeadsUp_suppressedGroupSummary() throws Exception {
         when(mPowerManager.isScreenOn()).thenReturn(true);
         when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
         when(mNotificationData.shouldSuppressStatusBar(any())).thenReturn(false);
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
-        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
 
         Notification n = new Notification.Builder(getContext(), "a")
@@ -396,15 +396,15 @@
                 UserHandle.of(0), null, 0);
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
 
-        assertFalse(mEntryManager.shouldPeek(entry, sbn));
+        assertFalse(mEntryManager.shouldHeadsUp(entry));
     }
 
     @Test
-    public void testShouldPeek_suppressedPeek() {
+    public void testShouldHeadsUp_suppressedHeadsUp() throws Exception {
         when(mPowerManager.isScreenOn()).thenReturn(true);
         when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
-        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
 
         when(mNotificationData.shouldSuppressPeek(any())).thenReturn(true);
@@ -414,15 +414,15 @@
                 UserHandle.of(0), null, 0);
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
 
-        assertFalse(mEntryManager.shouldPeek(entry, sbn));
+        assertFalse(mEntryManager.shouldHeadsUp(entry));
     }
 
     @Test
-    public void testShouldPeek_noSuppressedPeek() {
+    public void testShouldHeadsUp_noSuppressedHeadsUp() throws Exception {
         when(mPowerManager.isScreenOn()).thenReturn(true);
         when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
-        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
 
         when(mNotificationData.shouldSuppressPeek(any())).thenReturn(false);
@@ -432,31 +432,31 @@
                 UserHandle.of(0), null, 0);
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
 
-        assertTrue(mEntryManager.shouldPeek(entry, sbn));
+        assertTrue(mEntryManager.shouldHeadsUp(entry));
     }
 
     @Test
-    public void testPeek_disabledStatusBar() {
+    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 peek while disabled",
-                mStatusBar.shouldPeek(entry, sbn));
+        assertFalse("The panel shouldn't allow heads up while disabled",
+                mStatusBar.canHeadsUp(entry, sbn));
     }
 
     @Test
-    public void testPeek_disabledNotificationShade() {
+    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 peek while notitifcation shade disabled",
-                mStatusBar.shouldPeek(entry, sbn));
+        assertFalse("The panel shouldn't allow heads up while notification shade disabled",
+                mStatusBar.canHeadsUp(entry, sbn));
     }
 
     @Test
@@ -472,7 +472,7 @@
     }
 
     @Test
-    public void testPanelOpenForPeek() {
+    public void testPanelOpenForHeadsUp() {
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
         when(mNotificationList.size()).thenReturn(5);
@@ -690,10 +690,10 @@
 
     public static class TestableNotificationEntryManager extends NotificationEntryManager {
 
-        public TestableNotificationEntryManager(SystemServicesProxy systemServicesProxy,
+        public TestableNotificationEntryManager(IDreamManager dreamManager,
                 PowerManager powerManager, Context context) {
             super(context);
-            mSystemServicesProxy = systemServicesProxy;
+            mDreamManager = dreamManager;
             mPowerManager = powerManager;
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
index b22a646..1cceefa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
@@ -33,7 +33,7 @@
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.ExtensionController.Extension;
 import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
index 0a83a89..5f54bce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
@@ -14,12 +14,11 @@
 
 package com.android.systemui.utils.leaks;
 
-import android.content.Context;
 import android.testing.LeakCheck;
 
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 
 public class FakePluginManager implements PluginManager {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index ecda9620..f479126 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -20,7 +20,7 @@
 import android.util.ArrayMap;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.BatteryController;
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 41b3feb..5e87707 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -4026,6 +4026,8 @@
     // - AUTOFILL_DATASET_AUTHENTICATED
     // - AUTOFILL_INVALID_AUTHENTICATION
     // - AUTOFILL_INVALID_DATASET_AUTHENTICATION
+    // NOTE: starting on OS Q, it also added the following fields:
+    // Tag FIELD_AUTOFILL_TEXT_LEN: length of the error message provided by the service
     AUTOFILL_REQUEST = 907;
 
     // Tag of a field for a package of an autofill service
@@ -4102,6 +4104,8 @@
     // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
     // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
     // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+    // NOTE: starting on OS Q, it also added the following fields:
+    // Tag FIELD_AUTOFILL_TEXT_LEN: length of the error message provided by the service
     AUTOFILL_DATA_SAVE_REQUEST = 918;
 
     // An auto-fill session was finished
@@ -5922,7 +5926,7 @@
     // Tag used to determine what type of charging was started/ended
     // 1 = Plugged AC
     // 2 = Plugged USB
-    // 3 = Wireless
+    // 4 = Wireless
     FIELD_PLUG_TYPE = 1421;
 
     // ACTION: USB-C Connector connected.
@@ -6443,7 +6447,7 @@
 
     // OPEN: Settings > System > Input & Gesture > Reach up gesture
     // OS: Q
-    SETTINGS_GESTURE_REACH = 1557;
+    SETTINGS_GESTURE_WAKE_LOCK_SCREEN = 1557;
 
     // OPEN: Emergency dialer opened
     // CLOSE: Emergency dialer closed
@@ -6517,6 +6521,34 @@
     // OS: Q
     MOBILE_NETWORK = 1571;
 
+    // Tag of a field for the length of a text
+    FIELD_AUTOFILL_TEXT_LEN = 1572;
+
+    // Action: the notification assistant is changing a notification
+    // OS: Q
+    NOTIFICATION_ASSISTANT_ADJUSTMENT = 1573;
+
+    // Subtype: The people attached to a notification was changed
+    ADJUSTMENT_KEY_PEOPLE = 1574;
+
+    // Subtype: The snooze options attached to a notification was changed
+    ADJUSTMENT_KEY_SNOOZE_CRITERIA = 1575;
+
+    // Subtype: The group of a notification was changed
+    ADJUSTMENT_KEY_GROUP_KEY = 1576;
+
+    // Subtype: The user sentiment of a notification was changed
+    ADJUSTMENT_KEY_USER_SENTIMENT = 1577;
+
+    // Subtype: New actions have been added to a notification
+    ADJUSTMENT_KEY_SMART_ACTIONS = 1578;
+
+    // Subtype: New smart replies have been added to a notification
+    ADJUSTMENT_KEY_SMART_REPLIES = 1579;
+
+    // Subtype: The importance of a notification has been changed
+    ADJUSTMENT_KEY_IMPORTANCE = 1580;
+
     // ---- End Q Constants, all Q constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 7f8989d..033e996 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -479,6 +479,9 @@
 
   // Hardware revision (EVT, DVT, PVT etc.)
   optional string hardware_revision = 124;
+
+  // Total wifi link layer usage data over the logging duration in ms.
+  optional WifiLinkLayerUsageStats wifi_link_layer_usage_stats = 125;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -1654,4 +1657,21 @@
 
   // Num of installed Passpoint profile with same eap method
   optional int32 count = 2;
+}
+
+message WifiLinkLayerUsageStats {
+  // Total logging duration in ms.
+  optional int64 logging_duration_ms = 1;
+
+  // Total time the wifi radio is on in ms over the logging duration.
+  optional int64 radio_on_time_ms = 2;
+
+  // Total time the wifi radio is doing tx in ms over the logging duration.
+  optional int64 radio_tx_time_ms = 3;
+
+  // Total time the wifi radio is doing rx in ms over the logging duration.
+  optional int64 radio_rx_time_ms = 4;
+
+  // Total time the wifi radio is scanning in ms over the logging duration.
+  optional int64 radio_scan_time_ms = 5;
 }
\ No newline at end of file
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..6918275 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());
         }
@@ -2790,7 +2787,7 @@
     }
 
     @Override
-    public void onClientChange(boolean serviceInfoChanged) {
+    public void onClientChangeLocked(boolean serviceInfoChanged) {
         AccessibilityManagerService.UserState userState = getUserStateLocked(mCurrentUserId);
         onUserStateChangedLocked(userState);
         if (serviceInfoChanged) {
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/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 b71d7a7..da52d40 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1834,7 +1834,7 @@
 
                 if (provider.widgets.isEmpty()) {
                     // cancel the future updates
-                    cancelBroadcasts(provider);
+                    cancelBroadcastsLocked(provider);
 
                     // send the broacast saying that the provider is not in use any more
                     sendDisabledIntentLocked(provider);
@@ -1843,18 +1843,16 @@
         }
     }
 
-    private void cancelBroadcasts(Provider provider) {
+    private void cancelBroadcastsLocked(Provider provider) {
         if (DEBUG) {
-            Slog.i(TAG, "cancelBroadcasts() for " + provider);
+            Slog.i(TAG, "cancelBroadcastsLocked() for " + provider);
         }
         if (provider.broadcast != null) {
-            mAlarmManager.cancel(provider.broadcast);
-            long token = Binder.clearCallingIdentity();
-            try {
-                provider.broadcast.cancel();
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+            final PendingIntent broadcast = provider.broadcast;
+            mSaveStateHandler.post(() -> {
+                    mAlarmManager.cancel(broadcast);
+                    broadcast.cancel();
+            });
             provider.broadcast = null;
         }
     }
@@ -2315,7 +2313,7 @@
         mProviders.remove(provider);
 
         // no need to send the DISABLE broadcast, since the receiver is gone anyway
-        cancelBroadcasts(provider);
+        cancelBroadcastsLocked(provider);
     }
 
     private void sendEnableIntentLocked(Provider p) {
@@ -2369,17 +2367,14 @@
                 Binder.restoreCallingIdentity(token);
             }
             if (!alreadyRegistered) {
-                long period = provider.info.updatePeriodMillis;
-                if (period < MIN_UPDATE_PERIOD) {
-                    period = MIN_UPDATE_PERIOD;
-                }
-                final long oldId = Binder.clearCallingIdentity();
-                try {
+                // Set the alarm outside of our locks; we've latched the first-time
+                // invariant and established the PendingIntent safely.
+                final long period = Math.max(provider.info.updatePeriodMillis, MIN_UPDATE_PERIOD);
+                final PendingIntent broadcast = provider.broadcast;
+                mSaveStateHandler.post(() ->
                     mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            SystemClock.elapsedRealtime() + period, period, provider.broadcast);
-                } finally {
-                    Binder.restoreCallingIdentity(oldId);
-                }
+                            SystemClock.elapsedRealtime() + period, period, broadcast)
+                );
             }
         }
     }
@@ -3382,7 +3377,7 @@
                             // Reschedule for the new updatePeriodMillis (don't worry about handling
                             // it specially if updatePeriodMillis didn't change because we just sent
                             // an update, and the next one will be updatePeriodMillis from now).
-                            cancelBroadcasts(provider);
+                            cancelBroadcastsLocked(provider);
                             registerForBroadcastsLocked(provider, appWidgetIds);
                             // If it's currently showing, call back with the new
                             // AppWidgetProviderInfo.
diff --git a/services/art-profile b/services/art-profile
index 3c60eee..328f8f7 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -2254,8 +2254,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
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 8c8352f..78facf8 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -235,6 +235,13 @@
         }
     }
 
+    int getTargedSdkLocked() {
+        if (mInfo == null) {
+            return 0;
+        }
+        return mInfo.getServiceInfo().applicationInfo.targetSdkVersion;
+    }
+
     private boolean isSetupCompletedLocked() {
         final String setupComplete = Settings.Secure.getStringForUser(
                 mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
@@ -953,6 +960,7 @@
             pw.println();
             mInfo.dump(prefix2, pw);
             pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabel());
+            pw.print(prefix); pw.print("Target SDK: "); pw.println(getTargedSdkLocked());
         }
         pw.print(prefix); pw.print("Component from settings: ");
             pw.println(getComponentNameFromSettings());
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index ad80cc26..d1b09ca 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -29,6 +29,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.ServiceConnection;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
@@ -587,6 +588,7 @@
             }
             final RemoteFillService remoteService = getService();
             if (remoteService != null) {
+                if (sVerbose) Slog.v(LOG_TAG, "calling onFillRequest() for id=" + mRequest.getId());
                 try {
                     remoteService.mAutoFillService.onFillRequest(mRequest, mCallback);
                 } catch (RemoteException e) {
@@ -659,6 +661,7 @@
         public void run() {
             final RemoteFillService remoteService = getService();
             if (remoteService != null) {
+                if (sVerbose) Slog.v(LOG_TAG, "calling onSaveRequest()");
                 try {
                     remoteService.mAutoFillService.onSaveRequest(mRequest, mCallback);
                 } catch (RemoteException e) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index c9eb2d2..c1b620c 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -50,6 +50,7 @@
 import android.graphics.Rect;
 import android.metrics.LogMaker;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -63,6 +64,7 @@
 import android.service.autofill.Dataset;
 import android.service.autofill.FieldClassification;
 import android.service.autofill.FieldClassification.Match;
+import android.text.TextUtils;
 import android.service.autofill.FillContext;
 import android.service.autofill.FillRequest;
 import android.service.autofill.FillResponse;
@@ -398,7 +400,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())
@@ -413,7 +417,8 @@
                 final AutofillValue previousValue = previousSession
                         .findValueFromThisSessionOnlyLocked(autofillId);
                 if (previousValue != null) {
-                    return previousValue;
+                    return getSanitizedValue(createSanitizers(previousSession.getSaveInfoLocked()),
+                            autofillId, previousValue);
                 }
             }
         }
@@ -744,12 +749,17 @@
 
     private void onFillRequestFailureOrTimeout(int requestId, boolean timedOut,
             @Nullable CharSequence message) {
+        boolean showMessage = !TextUtils.isEmpty(message);
         synchronized (mLock) {
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#onFillRequestFailureOrTimeout(req=" + requestId
                         + ") rejected - session: " + id + " destroyed");
                 return;
             }
+            if (sDebug) {
+                Slog.d(TAG, "finishing session due to service "
+                        + (timedOut ? "timeout" : "failure"));
+            }
             mService.resetLastResponse();
             final LogMaker requestLog = mRequestLogs.get(requestId);
             if (requestLog == null) {
@@ -757,8 +767,21 @@
             } else {
                 requestLog.setType(timedOut ? MetricsEvent.TYPE_CLOSE : MetricsEvent.TYPE_FAILURE);
             }
+            if (showMessage) {
+                final int targetSdk = mService.getTargedSdkLocked();
+                if (targetSdk >= Build.VERSION_CODES.Q) {
+                    showMessage = false;
+                    Slog.w(TAG, "onFillRequestFailureOrTimeout(): not showing '" + message
+                            + "' because service's targetting API " + targetSdk);
+                }
+                if (message != null) {
+                    requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_TEXT_LEN,
+                            message.length());
+                }
+            }
         }
-        if (message != null) {
+        notifyUnavailableToClient(AutofillManager.STATE_UNKNOWN_FAILED);
+        if (showMessage) {
             getUiForShowing().showError(message, this);
         }
         removeSelf();
@@ -793,6 +816,7 @@
     @Override
     public void onSaveRequestFailure(@Nullable CharSequence message,
             @NonNull String servicePackageName) {
+        boolean showMessage = !TextUtils.isEmpty(message);
         synchronized (mLock) {
             mIsSaving = false;
 
@@ -801,12 +825,26 @@
                         + id + " destroyed");
                 return;
             }
+            if (showMessage) {
+                final int targetSdk = mService.getTargedSdkLocked();
+                if (targetSdk >= Build.VERSION_CODES.Q) {
+                    showMessage = false;
+                    Slog.w(TAG, "onSaveRequestFailure(): not showing '" + message
+                            + "' because service's targetting API " + targetSdk);
+                }
+            }
         }
-        LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST, servicePackageName)
+        final LogMaker log =
+                newLogMaker(MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST, servicePackageName)
                 .setType(MetricsEvent.TYPE_FAILURE);
+        if (message != null) {
+            log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_TEXT_LEN, message.length());
+        }
         mMetricsLogger.write(log);
 
-        getUiForShowing().showError(message, this);
+        if (showMessage) {
+            getUiForShowing().showError(message, this);
+        }
         removeSelf();
     }
 
@@ -1206,7 +1244,7 @@
             // - not autofilled but matches a dataset value -> manuallyFilledIds
             if ((state & ViewState.STATE_CHANGED) != 0) {
                 // Check if autofilled value was changed
-                if ((state & ViewState.STATE_AUTOFILLED) != 0) {
+                if ((state & ViewState.STATE_AUTOFILLED_ONCE) != 0) {
                     final String datasetId = viewState.getDatasetId();
                     if (datasetId == null) {
                         // Sanity check - should never happen.
@@ -2181,12 +2219,28 @@
                     // Must check if this update was caused by autofilling the view, in which
                     // case we just update the value, but not the UI.
                     final AutofillValue filledValue = viewState.getAutofilledValue();
-                    if (filledValue != null && filledValue.equals(value)) {
-                        if (sVerbose) {
-                            Slog.v(TAG, "ignoring autofilled change on id " + id);
+                    if (filledValue != null) {
+                        if (filledValue.equals(value)) {
+                            if (sVerbose) {
+                                Slog.v(TAG, "ignoring autofilled change on id " + id);
+                            }
+                            viewState.resetState(ViewState.STATE_CHANGED);
+                            return;
                         }
-                        return;
+                        else {
+                            if ((viewState.id.equals(this.mCurrentViewId)) &&
+                                    (viewState.getState() & ViewState.STATE_AUTOFILLED) != 0) {
+                                // Remove autofilled state once field is changed after autofilling.
+                                if (sVerbose) {
+                                    Slog.v(TAG, "field changed after autofill on id " + id);
+                                }
+                                viewState.resetState(ViewState.STATE_AUTOFILLED);
+                                final ViewState currentView = mViewStates.get(mCurrentViewId);
+                                currentView.maybeCallOnFillReady(flags);
+                            }
+                        }
                     }
+
                     // Update the internal state...
                     viewState.setState(ViewState.STATE_CHANGED);
 
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index e6cd7e0..a8dae03 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -69,8 +69,10 @@
     public static final int STATE_RESTARTED_SESSION = 0x100;
     /** View is the URL bar of a package on compat mode. */
     public  static final int STATE_URL_BAR = 0x200;
-    /** View was asked to autofil but failed to do so. */
+    /** View was asked to autofill but failed to do so. */
     public static final int STATE_AUTOFILL_FAILED = 0x400;
+    /** View has been autofilled at least once. */
+    public static final int STATE_AUTOFILLED_ONCE = 0x800;
 
     public final AutofillId id;
 
@@ -161,6 +163,9 @@
         } else {
             mState |= state;
         }
+        if (state == STATE_AUTOFILLED) {
+            mState |= STATE_AUTOFILLED_ONCE;
+        }
     }
 
     void resetState(int state) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 5962406..fe86ab3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -43,6 +43,8 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.LocalServices;
+import com.android.server.UiModeManagerInternal;
 import com.android.server.UiThread;
 import com.android.server.autofill.Helper;
 
@@ -69,6 +71,7 @@
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     private final @NonNull OverlayControl mOverlayControl;
+    private final @NonNull UiModeManagerInternal mUiModeMgr;
 
     public interface AutoFillUiCallback {
         void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent,
@@ -86,6 +89,7 @@
     public AutoFillUI(@NonNull Context context) {
         mContext = context;
         mOverlayControl = new OverlayControl(context);
+        mUiModeMgr = LocalServices.getService(UiModeManagerInternal.class);
     }
 
     public void setCallback(@NonNull AutoFillUiCallback callback) {
@@ -193,7 +197,9 @@
             }
             hideAllUiThread(callback);
             mFillUi = new FillUi(mContext, response, focusedId,
-                    filterText, mOverlayControl, serviceLabel, serviceIcon, new FillUi.Callback() {
+                    filterText, mOverlayControl, serviceLabel, serviceIcon,
+                    mUiModeMgr.isNightMode(),
+                    new FillUi.Callback() {
                 @Override
                 public void onResponsePicked(FillResponse response) {
                     log.setType(MetricsEvent.TYPE_DETAIL);
@@ -332,7 +338,7 @@
                     }
                     mMetricsLogger.write(log);
                 }
-            }, isUpdate, compatMode);
+            }, mUiModeMgr.isNightMode(), isUpdate, compatMode);
         });
     }
 
@@ -368,6 +374,7 @@
         pw.println("Autofill UI");
         final String prefix = "  ";
         final String prefix2 = "    ";
+        pw.print(prefix); pw.print("Night mode: "); pw.println(mUiModeMgr.isNightMode());
         if (mFillUi != null) {
             pw.print(prefix); pw.println("showsFillUi: true");
             mFillUi.dump(pw, prefix2);
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 68a495f..742d494 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -73,7 +73,10 @@
 final class FillUi {
     private static final String TAG = "FillUi";
 
-    private static final int THEME_ID = com.android.internal.R.style.Theme_DeviceDefault_Autofill;
+    private static final int THEME_ID_LIGHT =
+            com.android.internal.R.style.Theme_DeviceDefault_Light_Autofill;
+    private static final int THEME_ID_DARK =
+            com.android.internal.R.style.Theme_DeviceDefault_Autofill;
 
     private static final TypedValue sTempTypedValue = new TypedValue();
 
@@ -117,6 +120,8 @@
 
     private boolean mDestroyed;
 
+    private final int mThemeId;
+
     public static boolean isFullScreen(Context context) {
         if (sFullScreenMode != null) {
             if (sVerbose) Slog.v(TAG, "forcing full-screen mode to " + sFullScreenMode);
@@ -128,10 +133,13 @@
     FillUi(@NonNull Context context, @NonNull FillResponse response,
            @NonNull AutofillId focusedViewId, @NonNull @Nullable String filterText,
            @NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
-           @NonNull Drawable serviceIcon, @NonNull Callback callback) {
+           @NonNull Drawable serviceIcon, boolean nightMode, @NonNull Callback callback) {
+        if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
+        mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
         mCallback = callback;
         mFullScreen = isFullScreen(context);
-        mContext = new ContextThemeWrapper(context, THEME_ID);
+        mContext = new ContextThemeWrapper(context, mThemeId);
+
         final LayoutInflater inflater = LayoutInflater.from(mContext);
 
         final RemoteViews headerPresentation = response.getHeader();
@@ -216,7 +224,7 @@
             ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker);
             final View content;
             try {
-                response.getPresentation().setApplyTheme(THEME_ID);
+                response.getPresentation().setApplyTheme(mThemeId);
                 content = response.getPresentation().apply(mContext, decor, interceptionHandler);
                 container.addView(content);
             } catch (RuntimeException e) {
@@ -257,7 +265,7 @@
             RemoteViews.OnClickHandler clickBlocker = null;
             if (headerPresentation != null) {
                 clickBlocker = newClickBlocker();
-                headerPresentation.setApplyTheme(THEME_ID);
+                headerPresentation.setApplyTheme(mThemeId);
                 mHeader = headerPresentation.apply(mContext, null, clickBlocker);
                 final LinearLayout headerContainer =
                         decor.findViewById(R.id.autofill_dataset_header);
@@ -275,7 +283,7 @@
                     if (clickBlocker == null) { // already set for header
                         clickBlocker = newClickBlocker();
                     }
-                    footerPresentation.setApplyTheme(THEME_ID);
+                    footerPresentation.setApplyTheme(mThemeId);
                     mFooter = footerPresentation.apply(mContext, null, clickBlocker);
                     // Footer not supported on some platform e.g. TV
                     if (sVerbose) Slog.v(TAG, "adding footer");
@@ -302,7 +310,7 @@
                     final View view;
                     try {
                         if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
-                        presentation.setApplyTheme(THEME_ID);
+                        presentation.setApplyTheme(mThemeId);
                         view = presentation.apply(mContext, null, interceptionHandler);
                     } catch (RuntimeException e) {
                         Slog.e(TAG, "Error inflating remote views", e);
@@ -732,6 +740,18 @@
         pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
         pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
         pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
+        pw.print(prefix); pw.print("theme id: "); pw.print(mThemeId);
+        switch (mThemeId) {
+            case THEME_ID_DARK:
+                pw.println(" (dark)");
+                break;
+            case THEME_ID_LIGHT:
+                pw.println(" (light)");
+                break;
+            default:
+                pw.println("(UNKNOWN_MODE)");
+                break;
+        }
         if (mWindow != null) {
             pw.print(prefix); pw.print("mWindow: ");
             final String prefix2 = prefix + "  ";
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 9d3d3cb..89b442e 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -72,9 +72,11 @@
  */
 final class SaveUi {
 
-    private static final String TAG = "AutofillSaveUi";
+    private static final String TAG = "SaveUi";
 
-    private static final int THEME_ID =
+    private static final int THEME_ID_LIGHT =
+            com.android.internal.R.style.Theme_DeviceDefault_Light_Autofill_Save;
+    private static final int THEME_ID_DARK =
             com.android.internal.R.style.Theme_DeviceDefault_Autofill_Save;
 
     public interface OnSaveListener {
@@ -144,6 +146,7 @@
     private final String mServicePackageName;
     private final ComponentName mComponentName;
     private final boolean mCompatMode;
+    private final int mThemeId;
 
     private boolean mDestroyed;
 
@@ -152,7 +155,9 @@
            @Nullable String servicePackageName, @NonNull ComponentName componentName,
            @NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
            @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
-           boolean isUpdate, boolean compatMode) {
+           boolean nightMode, boolean isUpdate, boolean compatMode) {
+        if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
+        mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
         mPendingUi= pendingUi;
         mListener = new OneActionThenDestroyListener(listener);
         mOverlayControl = overlayControl;
@@ -160,7 +165,7 @@
         mComponentName = componentName;
         mCompatMode = compatMode;
 
-        context = new ContextThemeWrapper(context, THEME_ID);
+        context = new ContextThemeWrapper(context, mThemeId);
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view = inflater.inflate(R.layout.autofill_save, null);
 
@@ -250,7 +255,7 @@
         }
         yesButton.setOnClickListener((v) -> mListener.onSave());
 
-        mDialog = new Dialog(context, THEME_ID);
+        mDialog = new Dialog(context, mThemeId);
         mDialog.setContentView(view);
 
         // Dialog can be dismissed when touched outside, but the negative listener should not be
@@ -337,7 +342,7 @@
 
         try {
             // Create the remote view peer.
-            template.setApplyTheme(THEME_ID);
+            template.setApplyTheme(mThemeId);
             final View customSubtitleView = template.apply(context, null, handler);
 
             // Apply batch updates (if any).
@@ -556,7 +561,18 @@
         pw.print(prefix); pw.print("service: "); pw.println(mServicePackageName);
         pw.print(prefix); pw.print("app: "); pw.println(mComponentName.toShortString());
         pw.print(prefix); pw.print("compat mode: "); pw.println(mCompatMode);
-
+        pw.print(prefix); pw.print("theme id: "); pw.print(mThemeId);
+        switch (mThemeId) {
+            case THEME_ID_DARK:
+                pw.println(" (dark)");
+                break;
+            case THEME_ID_LIGHT:
+                pw.println(" (light)");
+                break;
+            default:
+                pw.println("(UNKNOWN_MODE)");
+                break;
+        }
         final View view = mDialog.getWindow().getDecorView();
         final int[] loc = view.getLocationOnScreen();
         pw.print(prefix); pw.print("coordinates: ");
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/Chunk.java b/services/backup/java/com/android/server/backup/encryption/chunk/Chunk.java
new file mode 100644
index 0000000..5bec1a9
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunk/Chunk.java
@@ -0,0 +1,54 @@
+package com.android.server.backup.encryption.chunk;
+
+import android.util.proto.ProtoInputStream;
+
+import java.io.IOException;
+
+/**
+ * Information about a chunk entry in a protobuf. Only used for reading from a {@link
+ * ProtoInputStream}.
+ */
+public class Chunk {
+    /**
+     * Reads a Chunk from a {@link ProtoInputStream}. Expects the message to be of format {@link
+     * ChunksMetadataProto.Chunk}.
+     *
+     * @param inputStream currently at a {@link ChunksMetadataProto.Chunk} message.
+     * @throws IOException when the message is not structured as expected or a field can not be
+     *     read.
+     */
+    static Chunk readFromProto(ProtoInputStream inputStream) throws IOException {
+        Chunk result = new Chunk();
+
+        while (inputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (inputStream.getFieldNumber()) {
+                case (int) ChunksMetadataProto.Chunk.HASH:
+                    result.mHash = inputStream.readBytes(ChunksMetadataProto.Chunk.HASH);
+                    break;
+                case (int) ChunksMetadataProto.Chunk.LENGTH:
+                    result.mLength = inputStream.readInt(ChunksMetadataProto.Chunk.LENGTH);
+                    break;
+            }
+        }
+
+        return result;
+    }
+
+    private int mLength;
+    private byte[] mHash;
+
+    /** Private constructor. This class should only be instantiated by calling readFromProto. */
+    private Chunk() {
+        // Set default values for fields in case they are not available in the proto.
+        mHash = new byte[]{};
+        mLength = 0;
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    public byte[] getHash() {
+        return mHash;
+    }
+}
\ No newline at end of file
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkListing.java b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkListing.java
new file mode 100644
index 0000000..2d2e88a
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkListing.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 android.annotation.Nullable;
+import android.util.proto.ProtoInputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Chunk listing in a format optimized for quick look-up of chunks via their hash keys. This is
+ * useful when building an incremental backup. After a chunk has been produced, the algorithm can
+ * quickly look up whether the chunk existed in the previous backup by checking this chunk listing.
+ * It can then tell the server to use that chunk, through telling it the position and length of the
+ * chunk in the previous backup's blob.
+ */
+public class ChunkListing {
+    /**
+     * Reads a ChunkListing from a {@link ProtoInputStream}. Expects the message to be of format
+     * {@link ChunksMetadataProto.ChunkListing}.
+     *
+     * @param inputStream Currently at a {@link ChunksMetadataProto.ChunkListing} message.
+     * @throws IOException when the message is not structured as expected or a field can not be
+     *     read.
+     */
+    public static ChunkListing readFromProto(ProtoInputStream inputStream) throws IOException {
+        Map<ChunkHash, Entry> entries = new HashMap();
+
+        long start = 0;
+
+        while (inputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            if (inputStream.getFieldNumber() == (int) ChunksMetadataProto.ChunkListing.CHUNKS) {
+                long chunkToken = inputStream.start(ChunksMetadataProto.ChunkListing.CHUNKS);
+                Chunk chunk = Chunk.readFromProto(inputStream);
+                entries.put(new ChunkHash(chunk.getHash()), new Entry(start, chunk.getLength()));
+                start += chunk.getLength();
+                inputStream.end(chunkToken);
+            }
+        }
+
+        return new ChunkListing(entries);
+    }
+
+    private final Map<ChunkHash, Entry> mChunksByHash;
+
+    private ChunkListing(Map<ChunkHash, Entry> chunksByHash) {
+        mChunksByHash = Collections.unmodifiableMap(new HashMap<>(chunksByHash));
+    }
+
+    /** Returns {@code true} if there is a chunk with the given SHA-256 MAC key in the listing. */
+    public boolean hasChunk(ChunkHash hash) {
+        return mChunksByHash.containsKey(hash);
+    }
+
+    /**
+     * Returns the entry for the chunk with the given hash.
+     *
+     * @param hash The SHA-256 MAC of the plaintext of the chunk.
+     * @return The entry, containing position and length of the chunk in the backup blob, or null if
+     *     it does not exist.
+     */
+    @Nullable
+    public Entry getChunkEntry(ChunkHash hash) {
+        return mChunksByHash.get(hash);
+    }
+
+    /** Returns the number of chunks in this listing. */
+    public int getChunkCount() {
+        return mChunksByHash.size();
+    }
+
+    /** Information about a chunk entry in a backup blob - i.e., its position and length. */
+    public static final class Entry {
+        private final int mLength;
+        private final long mStart;
+
+        private Entry(long start, int length) {
+            mStart = start;
+            mLength = length;
+        }
+
+        /** Returns the length of the chunk in bytes. */
+        public int getLength() {
+            return mLength;
+        }
+
+        /** Returns the start position of the chunk in the backup blob, in bytes. */
+        public long getStart() {
+            return mStart;
+        }
+    }
+}
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/chunk/EncryptedChunkOrdering.java b/services/backup/java/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
new file mode 100644
index 0000000..3a6d1f6
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 java.util.Arrays;
+
+/**
+ * Holds the bytes of an encrypted {@link ChunksMetadataProto.ChunkOrdering}.
+ *
+ * <p>TODO(b/116575321): After all code is ported, remove the factory method and rename
+ * encryptedChunkOrdering() to getBytes().
+ */
+public class EncryptedChunkOrdering {
+    /**
+     * Constructs a new object holding the given bytes of an encrypted {@link
+     * ChunksMetadataProto.ChunkOrdering}.
+     *
+     * <p>Note that this just holds an ordering which is already encrypted, it does not encrypt the
+     * ordering.
+     */
+    public static EncryptedChunkOrdering create(byte[] encryptedChunkOrdering) {
+        return new EncryptedChunkOrdering(encryptedChunkOrdering);
+    }
+
+    private final byte[] mEncryptedChunkOrdering;
+
+    public byte[] encryptedChunkOrdering() {
+        return mEncryptedChunkOrdering;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof EncryptedChunkOrdering)) {
+            return false;
+        }
+
+        EncryptedChunkOrdering encryptedChunkOrdering = (EncryptedChunkOrdering) o;
+        return Arrays.equals(
+                mEncryptedChunkOrdering, encryptedChunkOrdering.mEncryptedChunkOrdering);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(mEncryptedChunkOrdering);
+    }
+
+    private EncryptedChunkOrdering(byte[] encryptedChunkOrdering) {
+        mEncryptedChunkOrdering = encryptedChunkOrdering;
+    }
+}
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/AgentException.java b/services/backup/java/com/android/server/backup/keyvalue/AgentException.java
new file mode 100644
index 0000000..e2ca351
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/keyvalue/AgentException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyvalue;
+
+/**
+ * This represents something wrong with a specific package. For example:
+ * <ul>
+ *     <li>Package unknown.
+ *     <li>Package is not eligible for backup anymore.
+ *     <li>Backup agent timed out.
+ *     <li>Backup agent wrote protected keys.
+ *     <li>...
+ * </ul>
+ *
+ * @see KeyValueBackupTask
+ * @see TaskException
+ */
+class AgentException extends BackupException {
+    static AgentException transitory() {
+        return new AgentException(/* transitory */ true);
+    }
+
+    static AgentException transitory(Exception cause) {
+        return new AgentException(/* transitory */ true, cause);
+    }
+
+    static AgentException permanent() {
+        return new AgentException(/* transitory */ false);
+    }
+
+    static AgentException permanent(Exception cause) {
+        return new AgentException(/* transitory */ false, cause);
+    }
+
+    private final boolean mTransitory;
+
+    private AgentException(boolean transitory) {
+        mTransitory = transitory;
+    }
+
+    private AgentException(boolean transitory, Exception cause) {
+        super(cause);
+        mTransitory = transitory;
+    }
+
+    boolean isTransitory() {
+        return mTransitory;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/BackupException.java b/services/backup/java/com/android/server/backup/keyvalue/BackupException.java
new file mode 100644
index 0000000..27b2d35
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/keyvalue/BackupException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyvalue;
+
+import android.util.AndroidException;
+
+/**
+ * Key-value backup task exception.
+ *
+ * @see AgentException
+ * @see TaskException
+ */
+class BackupException extends AndroidException {
+    BackupException() {}
+
+    BackupException(Exception cause) {
+        super(cause);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java
index 54e6b1d..bb8a1d1 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java
@@ -54,7 +54,7 @@
 public class KeyValueBackupReporter {
     @VisibleForTesting static final String TAG = "KeyValueBackupTask";
     private static final boolean DEBUG = BackupManagerService.DEBUG;
-    @VisibleForTesting static final boolean MORE_DEBUG = BackupManagerService.MORE_DEBUG || true;
+    @VisibleForTesting static final boolean MORE_DEBUG = BackupManagerService.MORE_DEBUG || false;
 
     static void onNewThread(String threadName) {
         if (DEBUG) {
@@ -153,16 +153,18 @@
                 mObserver, packageName, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
     }
 
-    void onBindAgentError(SecurityException e) {
-        Slog.d(TAG, "Error in bind/backup", e);
-    }
-
     void onAgentUnknown(String packageName) {
         Slog.d(TAG, "Package does not exist, skipping");
         BackupObserverUtils.sendBackupOnPackageResult(
                 mObserver, packageName, BackupManager.ERROR_PACKAGE_NOT_FOUND);
     }
 
+    void onBindAgentError(String packageName, SecurityException e) {
+        Slog.d(TAG, "Error in bind/backup", e);
+        BackupObserverUtils.sendBackupOnPackageResult(
+                mObserver, packageName, BackupManager.ERROR_AGENT_FAILURE);
+    }
+
     void onAgentError(String packageName) {
         if (MORE_DEBUG) {
             Slog.i(TAG, "Agent failure for " + packageName + ", re-staging");
@@ -190,6 +192,8 @@
     void onCallAgentDoBackupError(String packageName, boolean callingAgent, Exception e) {
         if (callingAgent) {
             Slog.e(TAG, "Error invoking agent on " + packageName + ": " + e);
+            BackupObserverUtils.sendBackupOnPackageResult(
+                    mObserver, packageName, BackupManager.ERROR_AGENT_FAILURE);
         } else {
             Slog.e(TAG, "Error before invoking agent on " + packageName + ": " + e);
         }
@@ -220,12 +224,8 @@
         }
     }
 
-    void onReadAgentDataError(String packageName, IOException e) {
-        Slog.w(TAG, "Unable read backup data for " + packageName + ": " + e);
-    }
-
-    void onWriteWidgetDataError(String packageName, IOException e) {
-        Slog.w(TAG, "Unable to save widget data for " + packageName + ": " + e);
+    void onAgentDataError(String packageName, IOException e) {
+        Slog.w(TAG, "Unable to read/write agent data for " + packageName + ": " + e);
     }
 
     void onDigestError(NoSuchAlgorithmException e) {
@@ -243,16 +243,12 @@
         }
     }
 
-    void onSendDataToTransport(String packageName) {
+    void onTransportPerformBackup(String packageName) {
         if (MORE_DEBUG) {
             Slog.v(TAG, "Sending non-empty data to transport for " + packageName);
         }
     }
 
-    void onNonIncrementalAndNonIncrementalRequired() {
-        Slog.e(TAG, "Transport requested non-incremental but already the case");
-    }
-
     void onEmptyData(PackageInfo packageInfo) {
         if (MORE_DEBUG) {
             Slog.i(TAG, "No backup data written, not calling transport");
@@ -302,13 +298,20 @@
                 /* extras */ null);
     }
 
+    void onPackageBackupNonIncrementalAndNonIncrementalRequired(String packageName) {
+        Slog.e(TAG, "Transport requested non-incremental but already the case");
+        BackupObserverUtils.sendBackupOnPackageResult(
+                mObserver, packageName, BackupManager.ERROR_TRANSPORT_ABORTED);
+        EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, packageName);
+    }
+
     void onPackageBackupTransportFailure(String packageName) {
         BackupObserverUtils.sendBackupOnPackageResult(
                 mObserver, packageName, BackupManager.ERROR_TRANSPORT_ABORTED);
         EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, packageName);
     }
 
-    void onPackageBackupError(String packageName, Exception e) {
+    void onPackageBackupTransportError(String packageName, Exception e) {
         Slog.e(TAG, "Transport error backing up " + packageName, e);
         BackupObserverUtils.sendBackupOnPackageResult(
                 mObserver, packageName, BackupManager.ERROR_TRANSPORT_ABORTED);
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 e915ce1..6904b3f 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -16,6 +16,7 @@
 
 package com.android.server.backup.keyvalue;
 
+import static android.app.ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL;
 import static android.os.ParcelFileDescriptor.MODE_CREATE;
 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
 import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
@@ -25,8 +26,8 @@
 import static com.android.server.backup.BackupManagerService.OP_PENDING;
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
-import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupDataInput;
@@ -47,7 +48,6 @@
 import android.os.SELinux;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -77,6 +77,8 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
@@ -173,10 +175,8 @@
     private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
     private static final String BLANK_STATE_FILE_NAME = "blank_state";
     private static final String PM_PACKAGE = BackupManagerService.PACKAGE_MANAGER_SENTINEL;
-    @VisibleForTesting
-    public static final String STAGING_FILE_SUFFIX = ".data";
-    @VisibleForTesting
-    public static final String NEW_STATE_FILE_SUFFIX = ".new";
+    @VisibleForTesting public static final String STAGING_FILE_SUFFIX = ".data";
+    @VisibleForTesting public static final String NEW_STATE_FILE_SUFFIX = ".new";
 
     /**
      * Creates a new {@link KeyValueBackupTask} for key-value backup operation, spins up a new
@@ -244,13 +244,13 @@
     private final int mCurrentOpToken;
     private final File mStateDirectory;
     private final File mDataDirectory;
+    private final File mBlankStateFile;
     private final List<String> mOriginalQueue;
     private final List<String> mQueue;
     private final List<String> mPendingFullBackups;
     private final Object mQueueLock;
     @Nullable private final DataChangedJournal mJournal;
 
-    private int mStatus;
     @Nullable private PerformFullTransportBackupTask mFullBackupTask;
     @Nullable private IBackupAgent mAgent;
     @Nullable private PackageInfo mCurrentPackage;
@@ -316,6 +316,7 @@
         mDataDirectory = mBackupManagerService.getDataDir();
         mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
         mQueueLock = mBackupManagerService.getQueueLock();
+        mBlankStateFile = new File(mStateDirectory, BLANK_STATE_FILE_NAME);
     }
 
     private void registerTask() {
@@ -331,45 +332,43 @@
     public void run() {
         Process.setThreadPriority(THREAD_PRIORITY);
 
-        boolean processQueue = startTask();
-        while (processQueue && !mQueue.isEmpty() && !mCancelled) {
-            String packageName = mQueue.remove(0);
-            if (PM_PACKAGE.equals(packageName)) {
-                processQueue = backupPm();
-            } else {
-                processQueue = backupPackage(packageName);
+        int status = BackupTransport.TRANSPORT_OK;
+        try {
+            startTask();
+            while (!mQueue.isEmpty() && !mCancelled) {
+                String packageName = mQueue.remove(0);
+                try {
+                    if (PM_PACKAGE.equals(packageName)) {
+                        backupPm();
+                    } else {
+                        backupPackage(packageName);
+                    }
+                } catch (AgentException e) {
+                    if (e.isTransitory()) {
+                        // We try again this package in the next backup pass.
+                        mBackupManagerService.dataChangedImpl(packageName);
+                    }
+                }
             }
+        } catch (TaskException e) {
+            if (e.isStateCompromised()) {
+                mBackupManagerService.resetBackupState(mStateDirectory);
+            }
+            revertTask();
+            status = e.getStatus();
         }
-        finishTask();
+        finishTask(status);
     }
 
-    /** Returns whether to consume next queue package. */
-    private boolean handleAgentResult(@Nullable PackageInfo packageInfo, RemoteResult result) {
-        if (result == RemoteResult.FAILED_THREAD_INTERRUPTED) {
-            // Not an explicit cancel, we need to flag it.
-            mCancelled = true;
-            mReporter.onAgentCancelled(packageInfo);
-            cleanUpAgentForAgentError();
-            return false;
+    /** Returns transport status. */
+    private int sendDataToTransport(@Nullable PackageInfo packageInfo)
+            throws AgentException, TaskException {
+        try {
+            return sendDataToTransport();
+        } catch (IOException e) {
+            mReporter.onAgentDataError(packageInfo.packageName, e);
+            throw TaskException.causedBy(e);
         }
-        if (result == RemoteResult.FAILED_CANCELLED) {
-            mReporter.onAgentCancelled(packageInfo);
-            cleanUpAgentForAgentError();
-            return false;
-        }
-        if (result == RemoteResult.FAILED_TIMED_OUT) {
-            mReporter.onAgentTimedOut(packageInfo);
-            cleanUpAgentForAgentError();
-            return true;
-        }
-        Preconditions.checkState(result.isPresent());
-        long agentResult = result.get();
-        if (agentResult == BackupAgent.RESULT_ERROR) {
-            mReporter.onAgentResultError(packageInfo);
-            cleanUpAgentForAgentError();
-            return true;
-        }
-        return sendDataToTransport();
     }
 
     @Override
@@ -378,11 +377,10 @@
     @Override
     public void operationComplete(long unusedResult) {}
 
-    /** Returns whether to consume next queue package. */
-    private boolean startTask() {
+    private void startTask() throws TaskException {
         if (mBackupManagerService.isBackupOperationInProgress()) {
             mReporter.onSkipBackup();
-            return false;
+            throw TaskException.create();
         }
 
         // Unfortunately full backup task constructor registers the task with BMS, so we have to
@@ -390,11 +388,9 @@
         mFullBackupTask = createFullBackupTask(mPendingFullBackups);
         registerTask();
 
-        mStatus = BackupTransport.TRANSPORT_OK;
-
         if (mQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
             mReporter.onEmptyQueueAtStart();
-            return false;
+            return;
         }
         // We only backup PM if it was explicitly in the queue or if it's incremental.
         boolean backupPm = mQueue.remove(PM_PACKAGE) || !mNonIncremental;
@@ -415,20 +411,18 @@
             if (pmState.length() <= 0) {
                 mReporter.onInitializeTransport(transportName);
                 mBackupManagerService.resetBackupState(mStateDirectory);
-                mStatus = transport.initializeDevice();
-                mReporter.onTransportInitialized(mStatus);
+                int status = transport.initializeDevice();
+                mReporter.onTransportInitialized(status);
+                if (status != BackupTransport.TRANSPORT_OK) {
+                    throw TaskException.stateCompromised();
+                }
             }
+        } catch (TaskException e) {
+            throw e;
         } catch (Exception e) {
             mReporter.onInitializeTransportError(e);
-            mStatus = BackupTransport.TRANSPORT_ERROR;
+            throw TaskException.stateCompromised();
         }
-
-        if (mStatus != BackupTransport.TRANSPORT_OK) {
-            mBackupManagerService.resetBackupState(mStateDirectory);
-            return false;
-        }
-
-        return true;
     }
 
     private PerformFullTransportBackupTask createFullBackupTask(List<String> packages) {
@@ -446,120 +440,82 @@
                 mUserInitiated);
     }
 
-    /** Returns whether to consume next queue package. */
-    private boolean backupPm() {
-        RemoteResult agentResult = null;
+    private void backupPm() throws TaskException {
+        mReporter.onStartPackageBackup(PM_PACKAGE);
+        mCurrentPackage = new PackageInfo();
+        mCurrentPackage.packageName = PM_PACKAGE;
+
         try {
-            mCurrentPackage = new PackageInfo();
-            mCurrentPackage.packageName = PM_PACKAGE;
-
-            // Since PM is running in the system process we can set up its agent directly.
-            BackupAgent pmAgent = mBackupManagerService.makeMetadataAgent();
-            mAgent = IBackupAgent.Stub.asInterface(pmAgent.onBind());
-
-            Pair<Integer, RemoteResult> statusAndResult = extractAgentData(PM_PACKAGE, mAgent);
-            mStatus = statusAndResult.first;
-            agentResult = statusAndResult.second;
-        } catch (Exception e) {
+            extractPmAgentData(mCurrentPackage);
+            int status = sendDataToTransport(mCurrentPackage);
+            cleanUpAgentForTransportStatus(status);
+        } catch (AgentException | TaskException e) {
             mReporter.onExtractPmAgentDataError(e);
-            mStatus = BackupTransport.TRANSPORT_ERROR;
+            cleanUpAgentForError(e);
+            // PM agent failure is task failure.
+            throw TaskException.stateCompromised(e);
         }
-
-        if (mStatus != BackupTransport.TRANSPORT_OK) {
-            // In this case either extractAgentData() already made the agent clean-up or we haven't
-            // prepared the state for calling the agent, in either case we don't need to clean-up.
-            mBackupManagerService.resetBackupState(mStateDirectory);
-            return false;
-        }
-
-        Preconditions.checkNotNull(agentResult);
-        return handleAgentResult(mCurrentPackage, agentResult);
     }
 
-    /** Returns whether to consume next queue package. */
-    private boolean backupPackage(String packageName) {
+    private void backupPackage(String packageName) throws AgentException, TaskException {
         mReporter.onStartPackageBackup(packageName);
-        mStatus = BackupTransport.TRANSPORT_OK;
+        mCurrentPackage = getPackageForBackup(packageName);
 
-        // Verify that the requested app is eligible for key-value backup.
-        RemoteResult agentResult = null;
         try {
-            mCurrentPackage = mPackageManager.getPackageInfo(
-                    packageName, PackageManager.GET_SIGNING_CERTIFICATES);
-            ApplicationInfo applicationInfo = mCurrentPackage.applicationInfo;
-            if (!AppBackupUtils.appIsEligibleForBackup(applicationInfo, mPackageManager)) {
-                // The manifest has changed. This won't happen again because the app won't be
-                // requesting further backups.
-                mReporter.onPackageNotEligibleForBackup(packageName);
-                return true;
-            }
-
-            if (AppBackupUtils.appGetsFullBackup(mCurrentPackage)) {
-                // Initially enqueued for key-value backup, but only supports full-backup now.
-                mReporter.onPackageEligibleForFullBackup(packageName);
-                return true;
-            }
-
-            if (AppBackupUtils.appIsStopped(applicationInfo)) {
-                // Just as it won't receive broadcasts, we won't run it for backup.
-                mReporter.onPackageStopped(packageName);
-                return true;
-            }
-
-            try {
-                mBackupManagerService.setWorkSource(new WorkSource(applicationInfo.uid));
-                IBackupAgent agent =
-                        mBackupManagerService.bindToAgentSynchronous(
-                                applicationInfo,
-                                ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
-                if (agent != null) {
-                    mAgent = agent;
-                    Pair<Integer, RemoteResult> statusAndResult =
-                            extractAgentData(packageName, agent);
-                    mStatus = statusAndResult.first;
-                    agentResult = statusAndResult.second;
-                } else {
-                    // Timeout waiting for the agent to bind.
-                    mStatus = BackupTransport.AGENT_ERROR;
-                }
-            } catch (SecurityException e) {
-                mReporter.onBindAgentError(e);
-                mStatus = BackupTransport.AGENT_ERROR;
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-            mStatus = BackupTransport.AGENT_UNKNOWN;
-        } finally {
-            mBackupManagerService.setWorkSource(null);
+            extractAgentData(mCurrentPackage);
+            int status = sendDataToTransport(mCurrentPackage);
+            cleanUpAgentForTransportStatus(status);
+        } catch (AgentException | TaskException e) {
+            cleanUpAgentForError(e);
+            throw e;
         }
-
-        if (mStatus != BackupTransport.TRANSPORT_OK) {
-            // In this case either extractAgentData() already made the agent clean-up or we haven't
-            // prepared the state for calling the agent, in either case we don't need to clean-up.
-            Preconditions.checkState(mAgent == null);
-
-            if (mStatus == BackupTransport.AGENT_ERROR) {
-                mReporter.onAgentError(packageName);
-                mBackupManagerService.dataChangedImpl(packageName);
-                mStatus = BackupTransport.TRANSPORT_OK;
-                return true;
-            }
-
-            if (mStatus == BackupTransport.AGENT_UNKNOWN) {
-                mReporter.onAgentUnknown(packageName);
-                mStatus = BackupTransport.TRANSPORT_OK;
-                return true;
-            }
-
-            // Transport-level failure, re-enqueue everything.
-            revertTask();
-            return false;
-        }
-
-        Preconditions.checkNotNull(agentResult);
-        return handleAgentResult(mCurrentPackage, agentResult);
     }
 
-    private void finishTask() {
+    private PackageInfo getPackageForBackup(String packageName) throws AgentException {
+        final PackageInfo packageInfo;
+        try {
+            packageInfo =
+                    mPackageManager.getPackageInfo(
+                            packageName, PackageManager.GET_SIGNING_CERTIFICATES);
+        } catch (PackageManager.NameNotFoundException e) {
+            mReporter.onAgentUnknown(packageName);
+            throw AgentException.permanent(e);
+        }
+        ApplicationInfo applicationInfo = packageInfo.applicationInfo;
+        if (!AppBackupUtils.appIsEligibleForBackup(applicationInfo, mPackageManager)) {
+            mReporter.onPackageNotEligibleForBackup(packageName);
+            throw AgentException.permanent();
+        }
+        if (AppBackupUtils.appGetsFullBackup(packageInfo)) {
+            mReporter.onPackageEligibleForFullBackup(packageName);
+            throw AgentException.permanent();
+        }
+        if (AppBackupUtils.appIsStopped(applicationInfo)) {
+            mReporter.onPackageStopped(packageName);
+            throw AgentException.permanent();
+        }
+        return packageInfo;
+    }
+
+    private IBackupAgent bindAgent(PackageInfo packageInfo) throws AgentException {
+        String packageName = packageInfo.packageName;
+        final IBackupAgent agent;
+        try {
+            agent =
+                    mBackupManagerService.bindToAgentSynchronous(
+                            packageInfo.applicationInfo, BACKUP_MODE_INCREMENTAL);
+            if (agent == null) {
+                mReporter.onAgentError(packageName);
+                throw AgentException.transitory();
+            }
+        } catch (SecurityException e) {
+            mReporter.onBindAgentError(packageName, e);
+            throw AgentException.transitory(e);
+        }
+        return agent;
+    }
+
+    private void finishTask(int status) {
         // Mark packages that we couldn't backup as pending backup.
         for (String packageName : mQueue) {
             mBackupManagerService.dataChangedImpl(packageName);
@@ -576,7 +532,7 @@
         // If we succeeded and this is the first time we've done a backup, we can record the current
         // backup dataset token.
         long currentToken = mBackupManagerService.getCurrentToken();
-        if ((mStatus == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) {
+        if ((status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) {
             try {
                 IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString);
                 mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet());
@@ -589,9 +545,14 @@
 
         synchronized (mQueueLock) {
             mBackupManagerService.setBackupRunning(false);
-            if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
+            if (status == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
                 mReporter.onTransportNotInitialized();
-                triggerTransportInitializationLocked();
+                try {
+                    triggerTransportInitializationLocked();
+                } catch (Exception e) {
+                    mReporter.onPendingInitializeTransportError(e);
+                    status = BackupTransport.TRANSPORT_ERROR;
+                }
             }
         }
 
@@ -605,7 +566,7 @@
         }
 
         if (!mCancelled
-                && mStatus == BackupTransport.TRANSPORT_OK
+                && status == BackupTransport.TRANSPORT_OK
                 && mFullBackupTask != null
                 && !mPendingFullBackups.isEmpty()) {
             mReporter.onStartFullBackup(mPendingFullBackups);
@@ -621,7 +582,7 @@
             mFullBackupTask.unregisterTask();
         }
         mTaskFinishedListener.onFinished(callerLogString);
-        mReporter.onBackupFinished(getBackupFinishedStatus(mCancelled, mStatus));
+        mReporter.onBackupFinished(getBackupFinishedStatus(mCancelled, status));
         mBackupManagerService.getWakelock().release();
     }
 
@@ -642,17 +603,12 @@
     }
 
     @GuardedBy("mQueueLock")
-    private void triggerTransportInitializationLocked() {
-        try {
-            IBackupTransport transport =
-                    mTransportClient.connectOrThrow("KVBT.triggerTransportInitializationLocked");
-            mBackupManagerService.getPendingInits().add(transport.name());
-            deletePmStateFile();
-            mBackupManagerService.backupNow();
-        } catch (Exception e) {
-            mReporter.onPendingInitializeTransportError(e);
-            mStatus = BackupTransport.TRANSPORT_ERROR;
-        }
+    private void triggerTransportInitializationLocked() throws Exception {
+        IBackupTransport transport =
+                mTransportClient.connectOrThrow("KVBT.triggerTransportInitializationLocked");
+        mBackupManagerService.getPendingInits().add(transport.name());
+        deletePmStateFile();
+        mBackupManagerService.backupNow();
     }
 
     /** Removes PM state, triggering initialization in the next key-value task. */
@@ -660,35 +616,69 @@
         new File(mStateDirectory, PM_PACKAGE).delete();
     }
 
+    /** Same as {@link #extractAgentData(PackageInfo)}, but only for PM package. */
+    private void extractPmAgentData(PackageInfo packageInfo) throws AgentException, TaskException {
+        Preconditions.checkArgument(packageInfo.packageName.equals(PM_PACKAGE));
+        BackupAgent pmAgent = mBackupManagerService.makeMetadataAgent();
+        mAgent = IBackupAgent.Stub.asInterface(pmAgent.onBind());
+        extractAgentData(packageInfo, mAgent);
+    }
+
     /**
-     * Returns a {@link Pair}. The first of the pair contains the status. In case the status is
-     * {@link BackupTransport#TRANSPORT_OK}, the second of the pair contains the agent result,
-     * otherwise {@code null}.
+     * Binds to the agent and extracts its backup data. If this method returns, the data in {@code
+     * mBackupData} is ready to be sent to the transport, otherwise it will throw.
+     *
+     * <p>This method leaves agent resources (agent binder, files and file-descriptors) opened that
+     * need to be cleaned up after terminating, either successfully or exceptionally. This clean-up
+     * can be done with methods {@link #cleanUpAgentForTransportStatus(int)} and {@link
+     * #cleanUpAgentForError(BackupException)}, depending on whether data was successfully sent to
+     * the transport or not. It's the caller responsibility to do the clean-up or delegate it.
      */
-    private Pair<Integer, RemoteResult> extractAgentData(String packageName, IBackupAgent agent) {
+    private void extractAgentData(PackageInfo packageInfo) throws AgentException, TaskException {
+        mBackupManagerService.setWorkSource(new WorkSource(packageInfo.applicationInfo.uid));
+        try {
+            mAgent = bindAgent(packageInfo);
+            extractAgentData(packageInfo, mAgent);
+        } finally {
+            mBackupManagerService.setWorkSource(null);
+        }
+    }
+
+    /**
+     * Calls agent {@link IBackupAgent#doBackup(ParcelFileDescriptor, ParcelFileDescriptor,
+     * ParcelFileDescriptor, long, IBackupCallback, int)} and waits for the result. If this method
+     * returns, the data in {@code mBackupData} is ready to be sent to the transport, otherwise it
+     * will throw.
+     *
+     * <p>This method creates files and file-descriptors for the agent that need to be deleted and
+     * closed after terminating, either successfully or exceptionally. This clean-up can be done
+     * with methods {@link #cleanUpAgentForTransportStatus(int)} and {@link
+     * #cleanUpAgentForError(BackupException)}, depending on whether data was successfully sent to
+     * the transport or not. It's the caller responsibility to do the clean-up or delegate it.
+     */
+    private void extractAgentData(PackageInfo packageInfo, IBackupAgent agent)
+            throws AgentException, TaskException {
+        String packageName = packageInfo.packageName;
         mReporter.onExtractAgentData(packageName);
 
-        File blankStateFile = new File(mStateDirectory, BLANK_STATE_FILE_NAME);
         mSavedStateFile = new File(mStateDirectory, packageName);
         mBackupDataFile = new File(mDataDirectory, packageName + STAGING_FILE_SUFFIX);
         mNewStateFile = new File(mStateDirectory, packageName + NEW_STATE_FILE_SUFFIX);
         mReporter.onAgentFilesReady(mBackupDataFile);
 
-        mSavedState = null;
-        mBackupData = null;
-        mNewState = null;
-
         boolean callingAgent = false;
         final RemoteResult agentResult;
         try {
-            File savedStateFileForAgent = (mNonIncremental) ? blankStateFile : mSavedStateFile;
+            File savedStateFileForAgent = (mNonIncremental) ? mBlankStateFile : mSavedStateFile;
             // MODE_CREATE to make an empty file if necessary
-            mSavedState = ParcelFileDescriptor.open(
-                    savedStateFileForAgent, MODE_READ_ONLY | MODE_CREATE);
-            mBackupData = ParcelFileDescriptor.open(
-                    mBackupDataFile, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
-            mNewState = ParcelFileDescriptor.open(
-                    mNewStateFile, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
+            mSavedState =
+                    ParcelFileDescriptor.open(savedStateFileForAgent, MODE_READ_ONLY | MODE_CREATE);
+            mBackupData =
+                    ParcelFileDescriptor.open(
+                            mBackupDataFile, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
+            mNewState =
+                    ParcelFileDescriptor.open(
+                            mNewStateFile, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
 
             if (!SELinux.restorecon(mBackupDataFile)) {
                 mReporter.onRestoreconFailed(mBackupDataFile);
@@ -713,15 +703,40 @@
                             "doBackup()");
         } catch (Exception e) {
             mReporter.onCallAgentDoBackupError(packageName, callingAgent, e);
-            cleanUpAgentForAgentError();
-            // TODO: Remove the check on callingAgent when RemoteCall supports local agent calls.
-            int status =
-                    callingAgent ? BackupTransport.AGENT_ERROR : BackupTransport.TRANSPORT_ERROR;
-            return Pair.create(status, null);
+            if (callingAgent) {
+                throw AgentException.transitory(e);
+            } else {
+                throw TaskException.create();
+            }
+        } finally {
+            mBlankStateFile.delete();
         }
-        blankStateFile.delete();
+        checkAgentResult(packageInfo, agentResult);
+    }
 
-        return Pair.create(BackupTransport.TRANSPORT_OK, agentResult);
+    private void checkAgentResult(PackageInfo packageInfo, RemoteResult result)
+            throws AgentException, TaskException {
+        if (result == RemoteResult.FAILED_THREAD_INTERRUPTED) {
+            // Not an explicit cancel, we need to flag it.
+            mCancelled = true;
+            mReporter.onAgentCancelled(packageInfo);
+            throw TaskException.create();
+        }
+        if (result == RemoteResult.FAILED_CANCELLED) {
+            mReporter.onAgentCancelled(packageInfo);
+            throw TaskException.create();
+        }
+        if (result == RemoteResult.FAILED_TIMED_OUT) {
+            mReporter.onAgentTimedOut(packageInfo);
+            throw AgentException.transitory();
+        }
+        Preconditions.checkState(result.isPresent());
+        long resultCode = result.get();
+        if (resultCode == BackupAgent.RESULT_ERROR) {
+            mReporter.onAgentResultError(packageInfo);
+            throw AgentException.transitory();
+        }
+        Preconditions.checkState(resultCode == BackupAgent.RESULT_SUCCESS);
     }
 
     private void agentFail(IBackupAgent agent, String message) {
@@ -801,94 +816,79 @@
         }
     }
 
-    /** Returns whether to consume next queue package. */
-    private boolean sendDataToTransport() {
+    /** Returns transport status. */
+    private int sendDataToTransport() throws AgentException, TaskException, IOException {
         Preconditions.checkState(mBackupData != null);
+        checkBackupData(mCurrentPackage.applicationInfo, mBackupDataFile);
 
         String packageName = mCurrentPackage.packageName;
-        ApplicationInfo applicationInfo = mCurrentPackage.applicationInfo;
-
-        boolean writingWidgetData = false;
-        try {
-            if (!validateBackupData(applicationInfo, mBackupDataFile)) {
-                cleanUpAgentForAgentError();
-                return true;
-            }
-            writingWidgetData = true;
-            writeWidgetPayloadIfAppropriate(mBackupData.getFileDescriptor(), packageName);
-        } catch (IOException e) {
-            if (writingWidgetData) {
-                mReporter.onWriteWidgetDataError(packageName, e);
-            } else {
-                mReporter.onReadAgentDataError(packageName, e);
-            }
-            cleanUpAgentForAgentError();
-            revertTask();
-            return false;
-        }
+        writeWidgetPayloadIfAppropriate(mBackupData.getFileDescriptor(), packageName);
 
         boolean nonIncremental = mSavedStateFile.length() == 0;
-        long size = mBackupDataFile.length();
-        if (size > 0) {
-            try (ParcelFileDescriptor backupData =
-                         ParcelFileDescriptor.open(mBackupDataFile, MODE_READ_ONLY)) {
-                IBackupTransport transport =
-                        mTransportClient.connectOrThrow("KVBT.sendDataToTransport()");
-                mReporter.onSendDataToTransport(packageName);
-                int flags = getPerformBackupFlags(mUserInitiated, nonIncremental);
-
-                mStatus = transport.performBackup(mCurrentPackage, backupData, flags);
-                if (mStatus == BackupTransport.TRANSPORT_OK) {
-                    mStatus = transport.finishBackup();
-                }
-            } catch (Exception e) {
-                mReporter.onPackageBackupError(packageName, e);
-                mStatus = BackupTransport.TRANSPORT_ERROR;
-            }
-        } else {
-            mReporter.onEmptyData(mCurrentPackage);
-            mStatus = BackupTransport.TRANSPORT_OK;
-        }
-
-        if (nonIncremental
-                && mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
-            mReporter.onNonIncrementalAndNonIncrementalRequired();
-            mStatus = BackupTransport.TRANSPORT_ERROR;
-        }
-
-
-        boolean processQueue = handleTransportStatus(mStatus, packageName, size);
-        // We might report quota exceeded to the agent in handleTransportStatus() above, so we
-        // only clean-up after it.
-        cleanUpAgentForTransportStatus(mStatus);
-        return processQueue;
+        int status = transportPerformBackup(mCurrentPackage, mBackupDataFile, nonIncremental);
+        handleTransportStatus(status, packageName, mBackupDataFile.length());
+        return status;
     }
 
-    /** Returns whether to consume next queue package. */
-    private boolean handleTransportStatus(int status, String packageName, long size) {
+    private int transportPerformBackup(
+            PackageInfo packageInfo, File backupDataFile, boolean nonIncremental)
+            throws TaskException {
+        String packageName = packageInfo.packageName;
+        long size = backupDataFile.length();
+        if (size <= 0) {
+            mReporter.onEmptyData(packageInfo);
+            return BackupTransport.TRANSPORT_OK;
+        }
+
+        int status;
+        try (ParcelFileDescriptor backupData =
+                ParcelFileDescriptor.open(backupDataFile, MODE_READ_ONLY)) {
+            IBackupTransport transport =
+                    mTransportClient.connectOrThrow("KVBT.transportPerformBackup()");
+            mReporter.onTransportPerformBackup(packageName);
+            int flags = getPerformBackupFlags(mUserInitiated, nonIncremental);
+
+            status = transport.performBackup(packageInfo, backupData, flags);
+            if (status == BackupTransport.TRANSPORT_OK) {
+                status = transport.finishBackup();
+            }
+        } catch (Exception e) {
+            mReporter.onPackageBackupTransportError(packageName, e);
+            throw TaskException.causedBy(e);
+        }
+
+        if (nonIncremental && status == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
+            mReporter.onPackageBackupNonIncrementalAndNonIncrementalRequired(packageName);
+            throw TaskException.create();
+        }
+
+        return status;
+    }
+
+    private void handleTransportStatus(int status, String packageName, long size)
+            throws TaskException, AgentException {
         if (status == BackupTransport.TRANSPORT_OK) {
             mReporter.onPackageBackupComplete(packageName, size);
-            return true;
-        }
-        if (status == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
-            mReporter.onPackageBackupRejected(packageName);
-            return true;
+            return;
         }
         if (status == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
             mReporter.onPackageBackupNonIncrementalRequired(mCurrentPackage);
             // Immediately retry the current package.
             mQueue.add(0, packageName);
-            return true;
+            return;
+        }
+        if (status == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+            mReporter.onPackageBackupRejected(packageName);
+            throw AgentException.permanent();
         }
         if (status == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
             mReporter.onPackageBackupQuotaExceeded(packageName);
             agentDoQuotaExceeded(mAgent, packageName, size);
-            return true;
+            throw AgentException.permanent();
         }
         // Any other error here indicates a transport-level failure.
         mReporter.onPackageBackupTransportFailure(packageName);
-        revertTask();
-        return false;
+        throw TaskException.forStatus(status);
     }
 
     private void agentDoQuotaExceeded(@Nullable IBackupAgent agent, String packageName, long size) {
@@ -908,19 +908,17 @@
     }
 
     /**
-     * For system apps and pseudo-apps always return {@code true}. For regular apps returns whether
-     * {@code backupDataFile} doesn't have any protected keys.
-     *
-     * <p>If the app has attempted to write any protected keys we also crash them.
+     * For system apps and pseudo-apps never throws. For regular apps throws {@link AgentException}
+     * if {@code backupDataFile} has any protected keys, also crashing the app.
      */
-    private boolean validateBackupData(
-            @Nullable ApplicationInfo applicationInfo, File backupDataFile) throws IOException {
+    private void checkBackupData(@Nullable ApplicationInfo applicationInfo, File backupDataFile)
+            throws IOException, AgentException {
         if (applicationInfo == null || (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
             // System apps and pseudo-apps can write what they want.
-            return true;
+            return;
         }
         try (ParcelFileDescriptor backupData =
-                     ParcelFileDescriptor.open(backupDataFile, MODE_READ_ONLY)) {
+                ParcelFileDescriptor.open(backupDataFile, MODE_READ_ONLY)) {
             BackupDataInput backupDataInput = new BackupDataInput(backupData.getFileDescriptor());
             while (backupDataInput.readNextHeader()) {
                 String key = backupDataInput.getKey();
@@ -928,12 +926,11 @@
                     mReporter.onAgentIllegalKey(mCurrentPackage, key);
                     // Crash them if they wrote any protected keys.
                     agentFail(mAgent, "Illegal backup key: " + key);
-                    return false;
+                    throw AgentException.permanent();
                 }
                 backupDataInput.skipEntityData();
             }
         }
-        return true;
     }
 
     private int getPerformBackupFlags(boolean userInitiated, boolean nonIncremental) {
@@ -1009,44 +1006,39 @@
         }
     }
 
-    /** Cleans-up after having called the agent. */
+    /**
+     * Cleans up agent resources opened by {@link #extractAgentData(PackageInfo)} for exceptional
+     * case.
+     *
+     * <p>Note: Declaring exception parameter so that the caller only calls this when an exception
+     * is thrown.
+     */
+    private void cleanUpAgentForError(BackupException exception) {
+        cleanUpAgent(StateTransaction.DISCARD_NEW);
+    }
+
+    /**
+     * Cleans up agent resources opened by {@link #extractAgentData(PackageInfo)} according to
+     * transport status returned in {@link #sendDataToTransport(PackageInfo)}.
+     */
     private void cleanUpAgentForTransportStatus(int status) {
-        updateFiles(status);
-        cleanUpAgent();
-    }
-
-    /** Cleans-up if we failed to call the agent. */
-    private void cleanUpAgentForAgentError() {
-        mBackupDataFile.delete();
-        mNewStateFile.delete();
-        cleanUpAgent();
-    }
-
-    private void updateFiles(int status) {
         switch (status) {
             case BackupTransport.TRANSPORT_OK:
-                mBackupDataFile.delete();
-                mNewStateFile.renameTo(mSavedStateFile);
+                cleanUpAgent(StateTransaction.COMMIT_NEW);
                 break;
             case BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED:
-                mSavedStateFile.delete();
-                mBackupDataFile.delete();
-                mNewStateFile.delete();
+                cleanUpAgent(StateTransaction.DISCARD_ALL);
                 break;
             default:
-                // Includes:
-                // * BackupTransport.TRANSPORT_PACKAGE_REJECTED
-                // * BackupTransport.TRANSPORT_QUOTA_EXCEEDED
-                // * BackupTransport.TRANSPORT_ERROR
-                mBackupDataFile.delete();
-                mNewStateFile.delete();
-                break;
+                // All other transport statuses are properly converted to agent or task exceptions.
+                throw new AssertionError();
         }
     }
 
-    /** Cleans-up file-descriptors and unbinds agent. */
-    private void cleanUpAgent() {
-        mAgent = null;
+    private void cleanUpAgent(@StateTransaction int stateTransaction) {
+        applyStateTransaction(stateTransaction);
+        mBackupDataFile.delete();
+        mBlankStateFile.delete();
         tryCloseFileDescriptor(mSavedState, "old state");
         tryCloseFileDescriptor(mBackupData, "backup data");
         tryCloseFileDescriptor(mNewState, "new state");
@@ -1058,6 +1050,24 @@
         if (mCurrentPackage.applicationInfo != null) {
             mBackupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
         }
+        mAgent = null;
+    }
+
+    private void applyStateTransaction(@StateTransaction int stateTransaction) {
+        switch (stateTransaction) {
+            case StateTransaction.COMMIT_NEW:
+                mNewStateFile.renameTo(mSavedStateFile);
+                break;
+            case StateTransaction.DISCARD_NEW:
+                mNewStateFile.delete();
+                break;
+            case StateTransaction.DISCARD_ALL:
+                mSavedStateFile.delete();
+                mNewStateFile.delete();
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown state transaction " + stateTransaction);
+        }
     }
 
     private void tryCloseFileDescriptor(@Nullable Closeable closeable, String logName) {
@@ -1079,4 +1089,16 @@
         mPendingCall = null;
         return result;
     }
+
+    @IntDef({
+        StateTransaction.COMMIT_NEW,
+        StateTransaction.DISCARD_NEW,
+        StateTransaction.DISCARD_ALL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface StateTransaction {
+        int COMMIT_NEW = 0;
+        int DISCARD_NEW = 1;
+        int DISCARD_ALL = 2;
+    }
 }
diff --git a/services/backup/java/com/android/server/backup/keyvalue/TaskException.java b/services/backup/java/com/android/server/backup/keyvalue/TaskException.java
new file mode 100644
index 0000000..08d2895
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/keyvalue/TaskException.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyvalue;
+
+import android.app.backup.BackupTransport;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * The key-value backup task has failed, no more packages will be processed and we shouldn't attempt
+ * any more backups now. These can be caused by transport failures (as opposed to agent failures).
+ *
+ * @see KeyValueBackupTask
+ * @see AgentException
+ */
+class TaskException extends BackupException {
+    private static final int DEFAULT_STATUS = BackupTransport.TRANSPORT_ERROR;
+
+    static TaskException stateCompromised() {
+        return new TaskException(/* stateCompromised */ true, DEFAULT_STATUS);
+    }
+
+    static TaskException stateCompromised(Exception cause) {
+        if (cause instanceof TaskException) {
+            TaskException exception = (TaskException) cause;
+            return new TaskException(cause, /* stateCompromised */ true, exception.getStatus());
+        }
+        return new TaskException(cause, /* stateCompromised */ true, DEFAULT_STATUS);
+    }
+
+    static TaskException forStatus(int status) {
+        Preconditions.checkArgument(
+                status != BackupTransport.TRANSPORT_OK, "Exception based on TRANSPORT_OK");
+        return new TaskException(/* stateCompromised */ false, status);
+    }
+
+    static TaskException causedBy(Exception cause) {
+        if (cause instanceof TaskException) {
+            return (TaskException) cause;
+        }
+        return new TaskException(cause, /* stateCompromised */ false, DEFAULT_STATUS);
+    }
+
+    static TaskException create() {
+        return new TaskException(/* stateCompromised */ false, DEFAULT_STATUS);
+    }
+
+    private final boolean mStateCompromised;
+    private final int mStatus;
+
+    private TaskException(Exception cause, boolean stateCompromised, int status) {
+        super(cause);
+        mStateCompromised = stateCompromised;
+        mStatus = status;
+    }
+
+    private TaskException(boolean stateCompromised, int status) {
+        mStateCompromised = stateCompromised;
+        mStatus = status;
+    }
+
+    boolean isStateCompromised() {
+        return mStateCompromised;
+    }
+
+    int getStatus() {
+        return mStatus;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 9af952d..c933833 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -105,7 +105,7 @@
                 try {
                     IBackupTransport transport =
                             transportClient.connectOrThrow(
-                                    "AppBackupUtils.appIsEligibleForBackupAtRuntime");
+                                    "AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport");
                     return transport.isAppEligibleForBackup(
                             packageInfo, AppBackupUtils.appGetsFullBackup(packageInfo));
                 } catch (Exception e) {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index ad2f82c..af33cbc 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;
@@ -509,7 +515,7 @@
             end = clampPositive(seed.maxWhenElapsed);
             flags = seed.flags;
             alarms.add(seed);
-            if (seed.operation == mTimeTickSender) {
+            if (seed.listener == mTimeTickTrigger) {
                 mLastTickAdded = mInjector.getCurrentTimeMillis();
             }
         }
@@ -534,7 +540,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 +578,7 @@
                     if (alarm.alarmClock != null) {
                         mNextAlarmClockMayChange = true;
                     }
-                    if (alarm.operation == mTimeTickSender) {
+                    if (alarm.listener == mTimeTickTrigger) {
                         mLastTickRemoved = mInjector.getCurrentTimeMillis();
                     }
                 } else {
@@ -690,8 +696,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 +828,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 +1116,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 +1314,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 +1464,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 +1910,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 +1922,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 +3677,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 +3801,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 +3859,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 +3917,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 +3945,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 +4355,6 @@
                 // PendingIntent alarm
                 mSendCount++;
 
-                if (alarm.priorityClass.priority == PRIO_TICK) {
-                    mLastTickIssued = nowELAPSED;
-                }
-
                 try {
                     alarm.operation.send(getContext(), 0,
                             mBackgroundIntent.putExtra(
@@ -4344,13 +4362,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 +4377,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/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 998e441..c2aec29 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -16,6 +16,15 @@
 
 package com.android.server;
 
+import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
+import static android.app.AppOpsManager.UID_STATE_CACHED;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
+import static android.app.AppOpsManager.UID_STATE_LAST_NON_RESTRICTED;
+import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
+import static android.app.AppOpsManager.UID_STATE_TOP;
+import static android.app.AppOpsManager._NUM_UID_STATE;
+
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
@@ -98,15 +107,6 @@
 import java.util.List;
 import java.util.Map;
 
-import static android.app.AppOpsManager._NUM_UID_STATE;
-import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
-import static android.app.AppOpsManager.UID_STATE_CACHED;
-import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
-import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
-import static android.app.AppOpsManager.UID_STATE_LAST_NON_RESTRICTED;
-import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
-import static android.app.AppOpsManager.UID_STATE_TOP;
-
 public class AppOpsService extends IAppOpsService.Stub {
     static final String TAG = "AppOps";
     static final boolean DEBUG = false;
@@ -1016,7 +1016,7 @@
                     scheduleWriteLocked();
                 }
             } else {
-                if (uidState.opModes.get(code) == mode) {
+                if (uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == mode) {
                     return;
                 }
                 if (mode == defaultMode) {
@@ -1971,6 +1971,7 @@
                             continue;
                         }
                         boolean doAllPackages = uidState.opModes != null
+                                && uidState.opModes.indexOfKey(code) >= 0
                                 && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND;
                         if (uidState.pkgOps != null) {
                             for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 7602090..5e8ffb7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -35,6 +35,9 @@
 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.os.Process.INVALID_UID;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
 
 import static com.android.internal.util.Preconditions.checkNotNull;
 
@@ -49,10 +52,12 @@
 import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
+import android.net.ConnectionInfo;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.PacketKeepalive;
 import android.net.IConnectivityManager;
 import android.net.IIpConnectivityMetrics;
+import android.net.INetd;
 import android.net.INetdEventCallback;
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
@@ -75,7 +80,6 @@
 import android.net.NetworkState;
 import android.net.NetworkUtils;
 import android.net.NetworkWatchlistManager;
-import android.net.Proxy;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
 import android.net.UidRange;
@@ -83,7 +87,9 @@
 import android.net.VpnService;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.NetworkEvent;
+import android.net.netlink.InetDiagMessage;
 import android.net.util.MultinetworkPolicyTracker;
+import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -153,7 +159,6 @@
 import com.android.server.connectivity.NetworkMonitor;
 import com.android.server.connectivity.NetworkNotificationManager;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
-import com.android.server.connectivity.PacManager;
 import com.android.server.connectivity.PermissionMonitor;
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.Tethering;
@@ -256,7 +261,8 @@
     // 0 is full bad, 100 is full good
     private int mDefaultInetConditionPublished = 0;
 
-    private INetworkManagementService mNetd;
+    private INetworkManagementService mNMS;
+    private INetd mNetd;
     private INetworkStatsService mStatsService;
     private INetworkPolicyManager mPolicyManager;
     private NetworkPolicyManagerInternal mPolicyManagerInternal;
@@ -387,9 +393,9 @@
     private static final int EVENT_PROMPT_UNVALIDATED = 29;
 
     /**
-     * used internally to (re)configure mobile data always-on settings.
+     * used internally to (re)configure always-on networks.
      */
-    private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30;
+    private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
 
     /**
      * used to add a network listener with a pending intent
@@ -745,6 +751,12 @@
         mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
                 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
 
+        // The default WiFi request is a background request so that apps using WiFi are
+        // migrated to a better network (typically ethernet) when one comes up, instead
+        // of staying on WiFi forever.
+        mDefaultWifiRequest = createDefaultInternetRequestForTransport(
+                NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
+
         mHandlerThread = new HandlerThread("ConnectivityServiceThread");
         mHandlerThread.start();
         mHandler = new InternalHandler(mHandlerThread.getLooper());
@@ -756,7 +768,7 @@
         mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
 
         mContext = checkNotNull(context, "missing Context");
-        mNetd = checkNotNull(netManager, "missing INetworkManagementService");
+        mNMS = checkNotNull(netManager, "missing INetworkManagementService");
         mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
         mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
         mPolicyManagerInternal = checkNotNull(
@@ -764,6 +776,7 @@
                 "missing NetworkPolicyManagerInternal");
         mProxyTracker = new ProxyTracker(context, mHandler, EVENT_PROXY_HAS_CHANGED);
 
+        mNetd = NetdService.getInstance();
         mKeyStore = KeyStore.getInstance();
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
 
@@ -846,7 +859,7 @@
 
         mTethering = makeTethering();
 
-        mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
+        mPermissionMonitor = new PermissionMonitor(mContext, mNMS);
 
         //set up the listener for user state for creating user VPNs
         IntentFilter intentFilter = new IntentFilter();
@@ -861,8 +874,8 @@
                 new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
 
         try {
-            mNetd.registerObserver(mTethering);
-            mNetd.registerObserver(mDataActivityObserver);
+            mNMS.registerObserver(mTethering);
+            mNMS.registerObserver(mDataActivityObserver);
         } catch (RemoteException e) {
             loge("Error registering observer :" + e);
         }
@@ -893,7 +906,7 @@
 
         mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
 
-        mDnsManager = new DnsManager(mContext, mNetd, mSystemProperties);
+        mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties);
         registerPrivateDnsSettingsCallbacks();
     }
 
@@ -909,7 +922,7 @@
                 return mDefaultRequest;
             }
         };
-        return new Tethering(mContext, mNetd, mStatsService, mPolicyManager,
+        return new Tethering(mContext, mNMS, mStatsService, mPolicyManager,
                 IoThread.get().getLooper(), new MockableSystemProperties(),
                 deps);
     }
@@ -941,8 +954,8 @@
     // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
     //    by subclassing SettingsObserver.
     @VisibleForTesting
-    void updateMobileDataAlwaysOn() {
-        mHandler.sendEmptyMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON);
+    void updateAlwaysOnNetworks() {
+        mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
     }
 
     // See FakeSettingsProvider comment above.
@@ -951,22 +964,30 @@
         mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
     }
 
-    private void handleMobileDataAlwaysOn() {
+    private void handleAlwaysOnNetworkRequest(
+            NetworkRequest networkRequest, String settingName, boolean defaultValue) {
         final boolean enable = toBool(Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 1));
-        final boolean isEnabled = (mNetworkRequests.get(mDefaultMobileDataRequest) != null);
+                mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
+        final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
         if (enable == isEnabled) {
             return;  // Nothing to do.
         }
 
         if (enable) {
             handleRegisterNetworkRequest(new NetworkRequestInfo(
-                    null, mDefaultMobileDataRequest, new Binder()));
+                    null, networkRequest, new Binder()));
         } else {
-            handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID);
+            handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID);
         }
     }
 
+    private void handleConfigureAlwaysOnNetworks() {
+        handleAlwaysOnNetworkRequest(
+                mDefaultMobileDataRequest,Settings.Global.MOBILE_DATA_ALWAYS_ON, true);
+        handleAlwaysOnNetworkRequest(mDefaultWifiRequest, Settings.Global.WIFI_ALWAYS_REQUESTED,
+                false);
+    }
+
     private void registerSettingsCallbacks() {
         // Watch for global HTTP proxy changes.
         mSettingsObserver.observe(
@@ -976,7 +997,12 @@
         // Watch for whether or not to keep mobile data always on.
         mSettingsObserver.observe(
                 Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON),
-                EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON);
+                EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
+
+        // Watch for whether or not to keep wifi always on.
+        mSettingsObserver.observe(
+                Settings.Global.getUriFor(Settings.Global.WIFI_ALWAYS_REQUESTED),
+                EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
     }
 
     private void registerPrivateDnsSettingsCallbacks() {
@@ -1473,6 +1499,20 @@
     };
 
     /**
+     * Ensures that the system cannot call a particular method.
+     */
+    private boolean disallowedBecauseSystemCaller() {
+        // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
+        // requestRouteToHost.
+        if (isSystem(Binder.getCallingUid())) {
+            log("This method exists only for app backwards compatibility"
+                    + " and must not be called by system services.");
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Ensure that a network route exists to deliver traffic to the specified
      * host via the specified network interface.
      * @param networkType the type of the network over which traffic to the
@@ -1483,6 +1523,9 @@
      */
     @Override
     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
+        if (disallowedBecauseSystemCaller()) {
+            return false;
+        }
         enforceChangePermission();
         if (mProtectedNetworks.contains(networkType)) {
             enforceConnectivityInternalPermission();
@@ -1560,7 +1603,7 @@
         if (DBG) log("Adding legacy route " + bestRoute +
                 " for UID/PID " + uid + "/" + Binder.getCallingPid());
         try {
-            mNetd.addLegacyRouteForNetId(netId, bestRoute, uid);
+            mNMS.addLegacyRouteForNetId(netId, bestRoute, uid);
         } catch (Exception e) {
             // never crash - catch them all
             if (DBG) loge("Exception trying to add a route: " + e);
@@ -1680,6 +1723,11 @@
                 "ConnectivityService");
     }
 
+    private boolean checkNetworkStackPermission() {
+        return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.NETWORK_STACK);
+    }
+
     private void enforceConnectivityRestrictedNetworksPermission() {
         try {
             mContext.enforceCallingOrSelfPermission(
@@ -1789,7 +1837,7 @@
     }
 
     void systemReady() {
-        loadGlobalProxy();
+        mProxyTracker.loadGlobalProxy();
         registerNetdEventCallback();
 
         synchronized (this) {
@@ -1806,8 +1854,8 @@
         // for user to unlock device too.
         updateLockdownVpn();
 
-        // Configure whether mobile data is always on.
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON));
+        // Create network requests for always-on networks.
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
 
@@ -1845,7 +1893,7 @@
 
         if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) {
             try {
-                mNetd.addIdleTimer(iface, timeout, type);
+                mNMS.addIdleTimer(iface, timeout, type);
             } catch (Exception e) {
                 // You shall not crash!
                 loge("Exception in setupDataActivityTracking " + e);
@@ -1864,7 +1912,7 @@
                               caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
             try {
                 // the call fails silently if no idle timer setup for this interface
-                mNetd.removeIdleTimer(iface);
+                mNMS.removeIdleTimer(iface);
             } catch (Exception e) {
                 loge("Exception in removeDataActivityTracking " + e);
             }
@@ -1872,6 +1920,18 @@
     }
 
     /**
+     * Update data activity tracking when network state is updated.
+     */
+    private void updateDataActivityTracking(NetworkAgentInfo newNetwork,
+            NetworkAgentInfo oldNetwork) {
+        if (newNetwork != null) {
+            setupDataActivityTracking(newNetwork);
+        }
+        if (oldNetwork != null) {
+            removeDataActivityTracking(oldNetwork);
+        }
+    }
+    /**
      * Reads the network specific MTU size from resources.
      * and set it on it's iface.
      */
@@ -1899,7 +1959,7 @@
 
         try {
             if (VDBG) log("Setting MTU size: " + iface + ", " + mtu);
-            mNetd.setMtu(iface, mtu);
+            mNMS.setMtu(iface, mtu);
         } catch (Exception e) {
             Slog.e(TAG, "exception in setMtu()" + e);
         }
@@ -2553,7 +2613,7 @@
         }
         nai.clearLingerState();
         if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
-            removeDataActivityTracking(nai);
+            updateDataActivityTracking(null /* newNetwork */, nai);
             notifyLockdownVpn(nai);
             ensureNetworkTransitionWakelock(nai.name());
         }
@@ -2573,7 +2633,7 @@
             // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
             // long time.
             try {
-                mNetd.removeNetwork(nai.network.netId);
+                mNMS.removeNetwork(nai.network.netId);
             } catch (Exception e) {
                 loge("Exception removing network: " + e);
             }
@@ -2771,20 +2831,6 @@
                 }
             }
 
-            // TODO: remove this code once we know that the Slog.wtf is never hit.
-            //
-            // Find all networks that are satisfying this request and remove the request
-            // from their request lists.
-            // TODO - it's my understanding that for a request there is only a single
-            // network satisfying it, so this loop is wasteful
-            for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) {
-                if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) {
-                    Slog.wtf(TAG, "Request " + nri.request + " satisfied by " +
-                            otherNai.name() + ", but mNetworkAgentInfos says " +
-                            (nai != null ? nai.name() : "null"));
-                }
-            }
-
             // Maintain the illusion.  When this request arrived, we might have pretended
             // that a network connected to serve it, even though the network was already
             // connected.  Now that this request has gone away, we might have to pretend
@@ -3098,8 +3144,8 @@
                     handlePromptUnvalidated((Network) msg.obj);
                     break;
                 }
-                case EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON: {
-                    handleMobileDataAlwaysOn();
+                case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
+                    handleConfigureAlwaysOnNetworks();
                     break;
                 }
                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
@@ -3409,31 +3455,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() {
@@ -3752,7 +3773,7 @@
                     Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
                     return false;
                 }
-                setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile));
+                setLockdownTracker(new LockdownVpnTracker(mContext, mNMS, this, vpn, profile));
             } else {
                 setLockdownTracker(null);
             }
@@ -4007,7 +4028,7 @@
                 loge("Starting user already has a VPN");
                 return;
             }
-            userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId);
+            userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId);
             mVpns.put(userId, userVpn);
             if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
                 updateLockdownVpn();
@@ -4527,6 +4548,10 @@
     // priority networks like Wi-Fi are active.
     private final NetworkRequest mDefaultMobileDataRequest;
 
+    // Request used to optionally keep wifi data active even when higher
+    // priority networks like ethernet are active.
+    private final NetworkRequest mDefaultWifiRequest;
+
     private NetworkAgentInfo getNetworkForRequest(int requestId) {
         synchronized (mNetworkForRequestId) {
             return mNetworkForRequestId.get(requestId);
@@ -4624,7 +4649,7 @@
         mDnsManager.updatePrivateDnsStatus(netId, newLp);
 
         // Start or stop clat accordingly to network state.
-        networkAgent.updateClat(mNetd);
+        networkAgent.updateClat(mNMS);
         if (isDefaultNetwork(networkAgent)) {
             handleApplyDefaultProxy(newLp.getHttpProxy());
         } else {
@@ -4663,9 +4688,9 @@
         final String prefix = "iface:" + iface;
         try {
             if (add) {
-                mNetd.getNetdService().wakeupAddInterface(iface, prefix, mark, mask);
+                mNetd.wakeupAddInterface(iface, prefix, mark, mask);
             } else {
-                mNetd.getNetdService().wakeupDelInterface(iface, prefix, mark, mask);
+                mNetd.wakeupDelInterface(iface, prefix, mark, mask);
             }
         } catch (Exception e) {
             loge("Exception modifying wakeup packet monitoring: " + e);
@@ -4681,7 +4706,7 @@
         for (String iface : interfaceDiff.added) {
             try {
                 if (DBG) log("Adding iface " + iface + " to network " + netId);
-                mNetd.addInterfaceToNetwork(iface, netId);
+                mNMS.addInterfaceToNetwork(iface, netId);
                 wakeupModifyInterface(iface, caps, true);
             } catch (Exception e) {
                 loge("Exception adding interface: " + e);
@@ -4691,7 +4716,7 @@
             try {
                 if (DBG) log("Removing iface " + iface + " from network " + netId);
                 wakeupModifyInterface(iface, caps, false);
-                mNetd.removeInterfaceFromNetwork(iface, netId);
+                mNMS.removeInterfaceFromNetwork(iface, netId);
             } catch (Exception e) {
                 loge("Exception removing interface: " + e);
             }
@@ -4715,7 +4740,7 @@
             if (route.hasGateway()) continue;
             if (VDBG) log("Adding Route [" + route + "] to network " + netId);
             try {
-                mNetd.addRoute(netId, route);
+                mNMS.addRoute(netId, route);
             } catch (Exception e) {
                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
                     loge("Exception in addRoute for non-gateway: " + e);
@@ -4726,7 +4751,7 @@
             if (route.hasGateway() == false) continue;
             if (VDBG) log("Adding Route [" + route + "] to network " + netId);
             try {
-                mNetd.addRoute(netId, route);
+                mNMS.addRoute(netId, route);
             } catch (Exception e) {
                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
                     loge("Exception in addRoute for gateway: " + e);
@@ -4737,7 +4762,7 @@
         for (RouteInfo route : routeDiff.removed) {
             if (VDBG) log("Removing Route [" + route + "] from network " + netId);
             try {
-                mNetd.removeRoute(netId, route);
+                mNMS.removeRoute(netId, route);
             } catch (Exception e) {
                 loge("Exception in removeRoute: " + e);
             }
@@ -4849,7 +4874,7 @@
         final String newPermission = getNetworkPermission(newNc);
         if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) {
             try {
-                mNetd.setNetworkPermission(nai.network.netId, newPermission);
+                mNMS.setNetworkPermission(nai.network.netId, newPermission);
             } catch (RemoteException e) {
                 loge("Exception in setNetworkPermission: " + e);
             }
@@ -4909,12 +4934,12 @@
             if (!newRanges.isEmpty()) {
                 final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
                 newRanges.toArray(addedRangesArray);
-                mNetd.addVpnUidRanges(nai.network.netId, addedRangesArray);
+                mNMS.addVpnUidRanges(nai.network.netId, addedRangesArray);
             }
             if (!prevRanges.isEmpty()) {
                 final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
                 prevRanges.toArray(removedRangesArray);
-                mNetd.removeVpnUidRanges(nai.network.netId, removedRangesArray);
+                mNMS.removeVpnUidRanges(nai.network.netId, removedRangesArray);
             }
         } catch (Exception e) {
             // Never crash!
@@ -5083,9 +5108,9 @@
 
     private void makeDefault(NetworkAgentInfo newNetwork) {
         if (DBG) log("Switching to new default network: " + newNetwork);
-        setupDataActivityTracking(newNetwork);
+
         try {
-            mNetd.setDefaultNetId(newNetwork.network.netId);
+            mNMS.setDefaultNetId(newNetwork.network.netId);
         } catch (Exception e) {
             loge("Exception setting default network :" + e);
         }
@@ -5258,6 +5283,7 @@
             }
         }
         if (isNewDefault) {
+            updateDataActivityTracking(newNetwork, oldDefaultNetwork);
             // Notify system services that this network is up.
             makeDefault(newNetwork);
             // Log 0 -> X and Y -> X default network transitions, where X is the new default.
@@ -5480,12 +5506,12 @@
             try {
                 // This should never fail.  Specifying an already in use NetID will cause failure.
                 if (networkAgent.isVPN()) {
-                    mNetd.createVirtualNetwork(networkAgent.network.netId,
+                    mNMS.createVirtualNetwork(networkAgent.network.netId,
                             !networkAgent.linkProperties.getDnsServers().isEmpty(),
                             (networkAgent.networkMisc == null ||
                                 !networkAgent.networkMisc.allowBypass));
                 } else {
-                    mNetd.createPhysicalNetwork(networkAgent.network.netId,
+                    mNMS.createPhysicalNetwork(networkAgent.network.netId,
                             getNetworkPermission(networkAgent.networkCapabilities));
                 }
             } catch (Exception e) {
@@ -5922,4 +5948,49 @@
             pw.println("    Get airplane mode.");
         }
     }
+
+    /**
+     * Caller either needs to be an active VPN, or hold the NETWORK_STACK permission
+     * for testing.
+     */
+    private Vpn enforceActiveVpnOrNetworkStackPermission() {
+        if (checkNetworkStackPermission()) {
+            return null;
+        }
+        final int uid = Binder.getCallingUid();
+        final int user = UserHandle.getUserId(uid);
+        synchronized (mVpns) {
+            Vpn vpn = mVpns.get(user);
+            try {
+                if (vpn.getVpnInfo().ownerUid == uid) return vpn;
+            } catch (NullPointerException e) {
+                /* vpn is null, or VPN is not connected and getVpnInfo() is null. */
+            }
+        }
+        throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK "
+                + "permission");
+    }
+
+    /**
+     * @param connectionInfo the connection to resolve.
+     * @return {@code uid} if the connection is found and the app has permission to observe it
+     * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
+     * connection is not found.
+     */
+    public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
+        final Vpn vpn = enforceActiveVpnOrNetworkStackPermission();
+        if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
+            throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
+        }
+
+        final int uid = InetDiagMessage.getConnectionOwnerUid(connectionInfo.protocol,
+                connectionInfo.local, connectionInfo.remote);
+
+        /* Filter out Uids not associated with the VPN. */
+        if (vpn != null && !vpn.appliesToUid(uid)) {
+            return INVALID_UID;
+        }
+
+        return uid;
+    }
 }
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index a34c2b9..26421a2 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -77,6 +77,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 +105,126 @@
 
 /**
  * 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_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 still on"
+       ]
+       STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n"]
+
+       STATE_ACTIVE -> STATE_INACTIVE [label="becomeInactiveIfAppropriateLocked()"]
+
+       STATE_INACTIVE -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"]
+
+       STATE_IDLE_PENDING -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"]
+
+       STATE_SENSING -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"]
+       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_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 {
@@ -148,21 +269,29 @@
     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;
 
-    private static String stateToString(int state) {
+    @VisibleForTesting
+    static String stateToString(int state) {
         switch (state) {
             case STATE_ACTIVE: return "ACTIVE";
             case STATE_INACTIVE: return "INACTIVE";
@@ -176,21 +305,30 @@
     }
 
     /** 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 +520,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 +562,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 +617,7 @@
             active = false;
         }
     }
-    private final MotionListener mMotionListener = new MotionListener();
+    @VisibleForTesting final MotionListener mMotionListener = new MotionListener();
 
     private final LocationListener mGenericLocationListener = new LocationListener() {
         @Override
@@ -521,7 +666,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";
@@ -594,7 +740,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
          */
@@ -1360,6 +1506,50 @@
         }
     }
 
+    static class Injector {
+        private final Context mContext;
+
+        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() {
+            return (ConnectivityService) ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+        }
+
+        Constants getConstants(DeviceIdleController controller, Handler handler,
+                ContentResolver resolver) {
+            return controller.new Constants(handler, resolver);
+        }
+
+        LocationManager getLocationManager() {
+            return mContext.getSystemService(LocationManager.class);
+        }
+
+        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 +1563,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 +1629,7 @@
                 }
             }
 
-            mConstants = new Constants(mHandler, getContext().getContentResolver());
+            mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
 
             readConfigFileLocked();
             updateWhitelistAppIdsLocked();
@@ -1459,20 +1654,19 @@
     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);
+                mConnectivityService = mInjector.getConnectivityService();
                 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
                         ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
                 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
@@ -1495,8 +1689,7 @@
 
                 if (getContext().getResources().getBoolean(
                         com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
-                    mLocationManager = (LocationManager) getContext().getSystemService(
-                            Context.LOCATION_SERVICE);
+                    mLocationManager = mInjector.getLocationManager();
                     mLocationRequest = new LocationRequest()
                         .setQuality(LocationRequest.ACCURACY_FINE)
                         .setInterval(0)
@@ -1506,9 +1699,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();
 
@@ -2005,6 +2197,11 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isScreenOn() {
+        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 +2221,11 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isCharging() {
+        return mCharging;
+    }
+
     void updateChargingLocked(boolean charging) {
         if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
         if (!charging && mCharging) {
@@ -2071,6 +2273,18 @@
         }
     }
 
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setDeepEnabledForTest(boolean enabled) {
+        mDeepEnabled = enabled;
+    }
+
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setLightEnabledForTest(boolean enabled) {
+        mLightEnabled = enabled;
+    }
+
     void becomeInactiveIfAppropriateLocked() {
         if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
         if ((!mScreenOn && !mCharging) || mForceIdle) {
@@ -2093,7 +2307,7 @@
         }
     }
 
-    void resetIdleManagementLocked() {
+    private void resetIdleManagementLocked() {
         mNextIdlePendingDelay = 0;
         mNextIdleDelay = 0;
         mNextLightIdleDelay = 0;
@@ -2104,7 +2318,7 @@
         mAnyMotionDetector.stop();
     }
 
-    void resetLightIdleManagementLocked() {
+    private void resetLightIdleManagementLocked() {
         cancelLightAlarmLocked();
     }
 
@@ -2117,6 +2331,21 @@
         }
     }
 
+    /**
+     * 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) {
+        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 +2429,18 @@
         }
     }
 
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setLocationManagerForTest(LocationManager lm) {
+        mLocationManager = lm;
+    }
+
+    @VisibleForTesting
+    int getState() {
+        return mState;
+    }
+
+    @VisibleForTesting
     void stepIdleStateLocked(String reason) {
         if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
         EventLogTags.writeDeviceIdleStep();
@@ -2331,6 +2572,12 @@
         }
     }
 
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setActiveIdleOpsForTest(int count) {
+        mActiveIdleOpCount = count;
+    }
+
     void setJobsActive(boolean active) {
         synchronized (this) {
             mJobsActive = active;
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 380f6a7..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;
@@ -1490,23 +1525,19 @@
         }
     }
 
-    private static final String TUNNEL_OP = "STOPSHIP"; // = AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
+    private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
 
     private void enforceTunnelPermissions(String callingPackage) {
         checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
-        if (false) { // STOPSHIP if this line is present
-            switch (getAppOpsManager().noteOp(
-                        TUNNEL_OP,
-                        Binder.getCallingUid(), callingPackage)) {
-                case AppOpsManager.MODE_DEFAULT:
-                    mContext.enforceCallingOrSelfPermission(
-                            android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
-                    break;
-                case AppOpsManager.MODE_ALLOWED:
-                    return;
-                default:
-                    throw new SecurityException("Request to ignore AppOps for non-legacy API");
-            }
+        switch (getAppOpsManager().noteOp(TUNNEL_OP, Binder.getCallingUid(), callingPackage)) {
+            case AppOpsManager.MODE_DEFAULT:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
+                break;
+            case AppOpsManager.MODE_ALLOWED:
+                return;
+            default:
+                throw new SecurityException("Request to ignore AppOps for non-legacy API");
         }
     }
 
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index ee01d86..96ce6a4 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -93,10 +93,12 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
         List<LooperStats.ExportedEntry> entries = mStats.getEntries();
         entries.sort(Comparator
-                .comparing((LooperStats.ExportedEntry entry) -> entry.threadName)
+                .comparing((LooperStats.ExportedEntry entry) -> entry.workSourceUid)
+                .thenComparing(entry -> entry.threadName)
                 .thenComparing(entry -> entry.handlerClassName)
                 .thenComparing(entry -> entry.messageName));
         String header = String.join(",", Arrays.asList(
+                "work_source_uid",
                 "thread_name",
                 "handler_class",
                 "message_name",
@@ -110,11 +112,11 @@
                 "exception_count"));
         pw.println(header);
         for (LooperStats.ExportedEntry entry : entries) {
-            pw.printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", 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\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);
         }
     }
 
@@ -127,7 +129,12 @@
     }
 
     private void setSamplingInterval(int samplingInterval) {
-        mStats.setSamplingInterval(samplingInterval);
+        if (samplingInterval > 0) {
+            mStats.setSamplingInterval(samplingInterval);
+        } else {
+            Slog.w(TAG, "Ignored invalid sampling interval (value must be positive): "
+                    + samplingInterval);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 1d163ee..de930f7 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -161,6 +161,8 @@
 
     private static final int MAX_UID_RANGES_PER_COMMAND = 10;
 
+    private static final  String[] EMPTY_STRING_ARRAY = new String[0];
+
     /**
      * Name representing {@link #setGlobalAlert(long)} limit when delivered to
      * {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -1234,18 +1236,12 @@
     @Override
     public void startTethering(String[] dhcpRange) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        // cmd is "tether start first_start first_stop second_start second_stop ..."
         // an odd number of addrs will fail
 
-        final Command cmd = new Command("tether", "start");
-        for (String d : dhcpRange) {
-            cmd.appendArg(d);
-        }
-
         try {
-            mConnector.execute(cmd);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.tetherStart(dhcpRange);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -1253,9 +1249,9 @@
     public void stopTethering() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            mConnector.execute("tether", "stop");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.tetherStop();
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -1263,25 +1259,21 @@
     public boolean isTetheringStarted() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("tether", "status");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            final boolean isEnabled = mNetdService.tetherIsEnabled();
+            return isEnabled;
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
-
-        // 210 Tethering services started
-        event.checkCode(TetherStatusResult);
-        return event.getMessage().endsWith("started");
     }
 
     @Override
     public void tetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            mConnector.execute("tether", "interface", "add", iface);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.tetherInterfaceAdd(iface);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
         List<RouteInfo> routes = new ArrayList<>();
         // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
@@ -1294,9 +1286,9 @@
     public void untetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            mConnector.execute("tether", "interface", "remove", iface);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.tetherInterfaceRemove(iface);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         } finally {
             removeInterfaceFromLocalNetwork(iface);
         }
@@ -1306,11 +1298,10 @@
     public String[] listTetheredInterfaces() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            return NativeDaemonEvent.filterMessageList(
-                    mConnector.executeForList("tether", "interface", "list"),
-                    TetherInterfaceListResult);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            final List<String> result = mNetdService.tetherInterfaceList();
+            return result.toArray(EMPTY_STRING_ARRAY);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -1319,16 +1310,11 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
-        final Command cmd = new Command("tether", "dns", "set", netId);
-
-        for (String s : dns) {
-            cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
-        }
 
         try {
-            mConnector.execute(cmd);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.tetherDnsSet(netId, dns);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -1336,10 +1322,10 @@
     public String[] getDnsForwarders() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            return NativeDaemonEvent.filterMessageList(
-                    mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            final List<String> result = mNetdService.tetherDnsList();
+            return result.toArray(EMPTY_STRING_ARRAY);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
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 d505a77..21f54dd 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -329,6 +329,12 @@
     @GuardedBy("mPackagesLock")
     private final SparseArray<String> mSandboxIds = new SparseArray<>();
 
+    /**
+     * List of volumes visible to any user.
+     * TODO: may be have a map of userId -> volumes?
+     */
+    private final CopyOnWriteArrayList<VolumeInfo> mVisibleVols = new CopyOnWriteArrayList<>();
+
     private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
 
     /** Holding lock for AppFuse business */
@@ -623,16 +629,12 @@
                         Slog.i(TAG, "Ignoring mount " + vol.getId() + " due to policy");
                         break;
                     }
-                    try {
-                        mVold.mount(vol.id, vol.mountFlags, vol.mountUserId);
-                    } catch (Exception e) {
-                        Slog.wtf(TAG, e);
-                    }
+                    mount(vol);
                     break;
                 }
                 case H_VOLUME_UNMOUNT: {
                     final VolumeInfo vol = (VolumeInfo) msg.obj;
-                    unmount(vol.getId());
+                    unmount(vol);
                     break;
                 }
                 case H_VOLUME_BROADCAST: {
@@ -869,6 +871,8 @@
                 addInternalVolumeLocked();
             }
 
+            mVisibleVols.clear();
+
             try {
                 mVold.reset();
 
@@ -1466,7 +1470,7 @@
                     = mContext.getPackageManager().getInstalledApplicationsAsUser(
                             PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
             synchronized (mPackagesLock) {
-                final ArraySet<String> userPackages = getPackagesForUserPL(userId);
+                final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId);
                 for (int i = appInfos.size() - 1; i >= 0; --i) {
                     if (appInfos.get(i).isInstantApp()) {
                         continue;
@@ -1523,7 +1527,7 @@
     }
 
     @GuardedBy("mPackagesLock")
-    private ArraySet<String> getPackagesForUserPL(int userId) {
+    private ArraySet<String> getAvailablePackagesForUserPL(int userId) {
         ArraySet<String> userPackages = mPackages.get(userId);
         if (userPackages == null) {
             userPackages = new ArraySet<>();
@@ -1535,8 +1539,24 @@
     private String[] getPackagesArrayForUser(int userId) {
         if (!ENABLE_ISOLATED_STORAGE) return EmptyArray.STRING;
 
+        final ArraySet<String> userPackages;
         synchronized (mPackagesLock) {
-            return getPackagesForUserPL(userId).toArray(new String[0]);
+            userPackages = getAvailablePackagesForUserPL(userId);
+            if (!userPackages.isEmpty()) {
+                return userPackages.toArray(new String[0]);
+            }
+        }
+        final List<ApplicationInfo> appInfos =
+                mContext.getPackageManager().getInstalledApplicationsAsUser(
+                        PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+        synchronized (mPackagesLock) {
+            for (int i = appInfos.size() - 1; i >= 0; --i) {
+                if (appInfos.get(i).isInstantApp()) {
+                    continue;
+                }
+                userPackages.add(appInfos.get(i).packageName);
+            }
+            return userPackages.toArray(new String[0]);
         }
     }
 
@@ -1747,8 +1767,15 @@
         if (isMountDisallowed(vol)) {
             throw new SecurityException("Mounting " + volId + " restricted by policy");
         }
+        mount(vol);
+    }
+
+    private void mount(VolumeInfo vol) {
         try {
             mVold.mount(vol.id, vol.mountFlags, vol.mountUserId);
+            if ((vol.mountFlags & VolumeInfo.MOUNT_FLAG_VISIBLE) != 0) {
+                mVisibleVols.add(vol);
+            }
         } catch (Exception e) {
             Slog.wtf(TAG, e);
         }
@@ -1759,8 +1786,15 @@
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         final VolumeInfo vol = findVolumeByIdOrThrow(volId);
+        unmount(vol);
+    }
+
+    private void unmount(VolumeInfo vol) {
         try {
             mVold.unmount(vol.id);
+            if ((vol.mountFlags & VolumeInfo.MOUNT_FLAG_VISIBLE) != 0) {
+                mVisibleVols.remove(vol);
+            }
         } catch (Exception e) {
             Slog.wtf(TAG, e);
         }
@@ -3596,6 +3630,14 @@
             pw.decreaseIndent();
 
             pw.println();
+            pw.println("mVisibleVols:");
+            pw.increaseIndent();
+            for (int i = 0; i < mVisibleVols.size(); i++) {
+                mVisibleVols.get(i).dump(pw);
+            }
+            pw.decreaseIndent();
+
+            pw.println();
             pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
             final Pair<String, Long> pair = StorageManager.getPrimaryStoragePathAndSize();
             if (pair == null) {
@@ -3716,7 +3758,7 @@
                 int userId) {
             final String sandboxId;
             synchronized (mPackagesLock) {
-                final ArraySet<String> userPackages = getPackagesForUserPL(userId);
+                final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId);
                 // If userPackages is empty, it means the user is not started yet, so no need to
                 // do anything now.
                 if (userPackages.isEmpty() || userPackages.contains(packageName)) {
@@ -3734,5 +3776,29 @@
                 Slog.wtf(TAG, e);
             }
         }
+
+        @Override
+        public String[] getVisibleVolumesForUser(int userId) {
+            final ArrayList<String> visibleVolsForUser = new ArrayList<>();
+            for (int i = mVisibleVols.size() - 1; i >= 0; --i) {
+                final VolumeInfo vol = mVisibleVols.get(i);
+                if (vol.isVisibleForUser(userId)) {
+                    visibleVolsForUser.add(getVolumeLabel(vol));
+                }
+            }
+            return visibleVolsForUser.toArray(new String[visibleVolsForUser.size()]);
+        }
+
+        private String getVolumeLabel(VolumeInfo vol) {
+            // STOPSHIP: Label needs to part of VolumeInfo and need to be passed on from vold
+            switch (vol.getType()) {
+                case VolumeInfo.TYPE_EMULATED:
+                    return "emulated";
+                case VolumeInfo.TYPE_PUBLIC:
+                    return vol.fsUuid == null ? vol.id : vol.fsUuid;
+                default:
+                    return null;
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 98b88cb..fb8894b 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -213,6 +213,8 @@
 
     private PhoneCapability mPhoneCapability = null;
 
+    private int mPreferredDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
     private final LocalLog mLocalLog = new LocalLog(100);
 
     private PreciseDataConnectionState mPreciseDataConnectionState =
@@ -752,6 +754,13 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE) != 0) {
+                        try {
+                            r.callback.onPreferredDataSubIdChanged(mPreferredDataSubId);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -1573,6 +1582,31 @@
         }
     }
 
+    public void notifyPreferredDataSubIdChanged(int preferredSubId) {
+        if (!checkNotifyPermission("notifyPreferredDataSubIdChanged()")) {
+            return;
+        }
+
+        if (VDBG) {
+            log("notifyPreferredDataSubIdChanged: preferredSubId=" + preferredSubId);
+        }
+
+        synchronized (mRecords) {
+            mPreferredDataSubId = preferredSubId;
+
+            for (Record r : mRecords) {
+                if (r.matchPhoneStateListenerEvent(
+                        PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE)) {
+                    try {
+                        r.callback.onPreferredDataSubIdChanged(preferredSubId);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -1610,6 +1644,7 @@
             pw.println("mBackgroundCallState=" + mBackgroundCallState);
             pw.println("mVoLteServiceState=" + mVoLteServiceState);
             pw.println("mPhoneCapability=" + mPhoneCapability);
+            pw.println("mPreferredDataSubId=" + mPreferredDataSubId);
 
             pw.decreaseIndent();
 
@@ -1647,6 +1682,7 @@
         intent.putExtras(data);
         // Pass the subscription along with the intent.
         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
+        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
         intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
@@ -1701,6 +1737,7 @@
         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
             intent.setAction(PhoneConstants.ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED);
             intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
+            intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
         }
         // If the phoneId is invalid, the broadcast is for overall call state.
         if (phoneId != SubscriptionManager.INVALID_PHONE_INDEX) {
diff --git a/services/core/java/com/android/server/UiModeManagerInternal.java b/services/core/java/com/android/server/UiModeManagerInternal.java
new file mode 100644
index 0000000..ef29069
--- /dev/null
+++ b/services/core/java/com/android/server/UiModeManagerInternal.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+/**
+ * UiModeManager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class UiModeManagerInternal {
+
+    public abstract boolean isNightMode();
+}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index cb03255..5538e72 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -42,31 +42,25 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.dreams.Sandman;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
-import android.text.TextUtils;
 import android.util.Slog;
 
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-
 import com.android.internal.R;
 import com.android.internal.app.DisableCarModeActivity;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.DumpUtils;
-import com.android.server.power.ShutdownThread;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 final class UiModeManagerService extends SystemService {
     private static final String TAG = UiModeManager.class.getSimpleName();
     private static final boolean LOG = false;
@@ -114,6 +108,8 @@
 
     private PowerManager.WakeLock mWakeLock;
 
+    private final LocalService mLocalService = new LocalService();
+
     public UiModeManagerService(Context context) {
         super(context);
     }
@@ -248,6 +244,7 @@
 
         }, TAG + ".onStart");
         publishBinderService(Context.UI_MODE_SERVICE, mService);
+        publishLocalService(UiModeManagerInternal.class, mLocalService);
     }
 
     private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
@@ -373,7 +370,8 @@
             pw.println("Current UI Mode Service state:");
             pw.print("  mDockState="); pw.print(mDockState);
                     pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
-            pw.print("  mNightMode="); pw.print(mNightMode);
+            pw.print("  mNightMode="); pw.print(mNightMode); pw.print(" (");
+                    pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") ");
                     pw.print(" mNightModeLocked="); pw.print(mNightModeLocked);
                     pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
                     pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
@@ -466,7 +464,7 @@
             uiMode |= mNightMode << 4;
         }
 
-        if (mPowerSave && !mNightModeLocked) {
+        if (mPowerSave) {
             uiMode &= ~Configuration.UI_MODE_NIGHT_NO;
             uiMode |= Configuration.UI_MODE_NIGHT_YES;
         }
@@ -845,4 +843,22 @@
             }
         }
     }
+
+    public final class LocalService extends UiModeManagerInternal {
+
+        @Override
+        public boolean isNightMode() {
+            synchronized (mLock) {
+                final boolean isIt = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_YES) != 0;
+                if (LOG) {
+                    Slog.d(TAG,
+                        "LocalService.isNightMode(): mNightMode=" + mNightMode
+                        + "; mComputedNightMode=" + mComputedNightMode
+                        + "; uiMode=" + mConfiguration.uiMode
+                        + "; isIt=" + isIt);
+                }
+                return isIt;
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 6d69fcd..0b836f0 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -94,7 +94,7 @@
         "media.metrics", // system/bin/mediametrics
         "media.codec", // vendor/bin/hw/android.hardware.media.omx@1.0-service
         "com.android.bluetooth",  // Bluetooth service
-        "statsd",  // Stats daemon
+        "/system/bin/statsd",  // Stats daemon
     };
 
     public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e5aa3f4..8e64b50 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -629,7 +629,7 @@
                 return false;
             }
 
-            IIntentSender target = mAm.getIntentSenderLocked(
+            IIntentSender target = mAm.mPendingIntentController.getIntentSender(
                     ActivityManager.INTENT_SENDER_SERVICE, callingPackage,
                     callingUid, userId, null, null, 0, new Intent[]{service},
                     new String[]{service.resolveType(mAm.mContext.getContentResolver())},
@@ -1466,9 +1466,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;
@@ -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();
@@ -2490,7 +2487,7 @@
                                  PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
             app.thread.scheduleCreateService(r, r.serviceInfo,
-                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
+                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                     app.getReportedProcState());
             r.postNotification();
             created = true;
@@ -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);
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 01421c7..a648b09a 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -43,6 +43,7 @@
 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;
@@ -51,6 +52,7 @@
 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;
@@ -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().
@@ -890,6 +973,8 @@
         mRemoved = true;
 
         releaseSelfIfNeeded();
+
+        mSupervisor.getKeyguardController().onDisplayRemoved(mDisplayId);
     }
 
     private void releaseSelfIfNeeded() {
@@ -909,6 +994,13 @@
         return mDisplayAccessUIDs;
     }
 
+    /**
+     * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+     */
+    boolean supportsSystemDecorations() {
+        return mDisplay.supportsSystemDecorations();
+    }
+
     private boolean shouldDestroyContentOnRemove() {
         return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
     }
@@ -918,6 +1010,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.
@@ -979,6 +1075,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;
+        }
+        mSupervisor.moveFocusableActivityToTop(top, 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;
     }
@@ -1040,6 +1187,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/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7533db1..37167c6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -42,6 +42,7 @@
 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;
@@ -90,6 +91,7 @@
 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
@@ -134,7 +136,6 @@
 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.POSTFIX_URI_PERMISSION;
 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;
@@ -369,7 +370,6 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
-import java.lang.ref.WeakReference;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -417,7 +417,6 @@
     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;
-    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
 
     // 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
@@ -563,6 +562,7 @@
     String mDeviceOwnerName;
 
     final UserController mUserController;
+    final PendingIntentController mPendingIntentController;
 
     final AppErrors mAppErrors;
 
@@ -665,11 +665,6 @@
     int mNextIsolatedProcessUid = 0;
 
     /**
-     * The currently running heavy-weight process, if any.
-     */
-    ProcessRecord mHeavyWeightProcess = null;
-
-    /**
      * Non-persistent appId whitelist for background restrictions
      */
     int[] mBackgroundAppIdWhitelist = new int[] {
@@ -826,18 +821,6 @@
     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
 
     /**
-     * Packages that the user has asked to have run in screen size
-     * compatibility mode instead of filling the screen.
-     */
-    final CompatModePackages mCompatModePackages;
-
-    /**
-     * Set of IntentSenderRecord objects that are currently active.
-     */
-    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
-            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
-
-    /**
      * Fingerprints (hashCode()) of stack traces that we've
      * already logged DropBox entries for.  Guarded by itself.  If
      * something (rogue user app) forces this over
@@ -1086,22 +1069,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 mBooting = false;
     @GuardedBy("this") boolean mCallFinishBooting = false;
     @GuardedBy("this") boolean mBootAnimationComplete = false;
-    @GuardedBy("this") boolean mLaunchWarningShown = false;
     private @GuardedBy("this") boolean mCheckedForSetup = false;
 
     final Context mContext;
@@ -1388,10 +1363,8 @@
 
     long mLastWriteTime = 0;
 
-    /**
-     * Set to true after the system has finished booting.
-     */
-    boolean mBooted = false;
+    /** Set to true after the system has finished booting. */
+    volatile boolean mBooted = false;
 
     /**
      * Current boot phase.
@@ -1432,7 +1405,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;
@@ -1440,9 +1412,6 @@
     static final int UPDATE_TIME_ZONE = 13;
     static final int PROC_START_TIMEOUT_MSG = 20;
     static final int KILL_APPLICATION_MSG = 22;
-    static final int FINALIZE_PENDING_INTENT_MSG = 23;
-    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
-    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
     static final int CLEAR_DNS_CACHE_MSG = 28;
@@ -1451,7 +1420,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 FINISH_BOOTING_MSG = 45;
     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;
@@ -1462,7 +1430,6 @@
     static final int IDLE_UIDS_MSG = 58;
     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
-    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
@@ -1498,8 +1465,6 @@
 
     PackageManagerInternal mPackageManagerInt;
 
-    boolean mHasHeavyWeightFeature;
-
     /**
      * Whether to force background check on all apps (for battery saver) or not.
      */
@@ -1581,12 +1546,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;
@@ -1661,21 +1620,6 @@
                 mServices.serviceForegroundCrash(
                     (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
             } break;
-            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
-                RemoteCallbackList<IResultReceiver> callbacks
-                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
-                int N = callbacks.beginBroadcast();
-                for (int i = 0; i < N; i++) {
-                    try {
-                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
-                    } catch (RemoteException e) {
-                    }
-                }
-                callbacks.finishBroadcast();
-                // We have to clean up the RemoteCallbackList here, because otherwise it will
-                // needlessly hold the enclosed callbacks until the remote process dies.
-                callbacks.kill();
-            } break;
             case UPDATE_TIME_ZONE: {
                 synchronized (ActivityManagerService.this) {
                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -1755,68 +1699,6 @@
                             false, userId, reason);
                 }
             } break;
-            case FINALIZE_PENDING_INTENT_MSG: {
-                ((PendingIntentRecord)msg.obj).completeFinalize();
-            } break;
-            case POST_HEAVY_NOTIFICATION_MSG: {
-                INotificationManager inm = NotificationManager.getService();
-                if (inm == null) {
-                    return;
-                }
-
-                ActivityRecord root = (ActivityRecord)msg.obj;
-                final WindowProcessController process = root.app;
-                if (process == null) {
-                    return;
-                }
-
-                try {
-                    Context context = mContext.createPackageContext(process.mInfo.packageName, 0);
-                    String text = mContext.getString(R.string.heavy_weight_notification,
-                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
-                    Notification notification =
-                            new Notification.Builder(context,
-                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
-                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                            .setWhen(0)
-                            .setOngoing(true)
-                            .setTicker(text)
-                            .setColor(mContext.getColor(
-                                    com.android.internal.R.color.system_notification_accent_color))
-                            .setContentTitle(text)
-                            .setContentText(
-                                    mContext.getText(R.string.heavy_weight_notification_detail))
-                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
-                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
-                                    new UserHandle(root.userId)))
-                            .build();
-                    try {
-                        inm.enqueueNotificationWithTag("android", "android", null,
-                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
-                                notification, root.userId);
-                    } catch (RuntimeException e) {
-                        Slog.w(ActivityManagerService.TAG,
-                                "Error showing notification for heavy-weight app", e);
-                    } catch (RemoteException e) {
-                    }
-                } catch (NameNotFoundException e) {
-                    Slog.w(TAG, "Unable to create context for heavy notification", e);
-                }
-            } break;
-            case CANCEL_HEAVY_NOTIFICATION_MSG: {
-                INotificationManager inm = NotificationManager.getService();
-                if (inm == null) {
-                    return;
-                }
-                try {
-                    inm.cancelNotificationWithTag("android", null,
-                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
-                } catch (RuntimeException e) {
-                    Slog.w(ActivityManagerService.TAG,
-                            "Error canceling notification for service", e);
-                } catch (RemoteException e) {
-                }
-            } break;
             case CHECK_EXCESSIVE_POWER_USE_MSG: {
                 synchronized (ActivityManagerService.this) {
                     checkExcessivePowerUsageLocked();
@@ -1853,17 +1735,6 @@
                 }
                 break;
             }
-            case FINISH_BOOTING_MSG: {
-                if (msg.arg1 != 0) {
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
-                    finishBooting();
-                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-                }
-                if (msg.arg2 != 0) {
-                    mAtmInternal.enableScreenAfterBoot(mBooted);
-                }
-                break;
-            }
             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
                 try {
                     Locale l = (Locale) msg.obj;
@@ -2430,7 +2301,6 @@
         mAppErrors = null;
         mAppOpsService = mInjector.getAppOpsService(null, null);
         mBatteryStatsService = null;
-        mCompatModePackages = null;
         mConstants = null;
         mHandler = null;
         mHandlerThread = null;
@@ -2442,9 +2312,11 @@
         mSystemThread = null;
         mUiHandler = injector.getUiHandler(null);
         mUserController = null;
+        mPendingIntentController = 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
@@ -2495,7 +2367,8 @@
         final File systemDir = SystemServiceManager.ensureSystemDir();
 
         // TODO: Move creation of battery stats service outside of activity manager service.
-        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
+        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir,
+                BackgroundThread.get().getHandler());
         mBatteryStatsService.getActiveStatistics().readLocked();
         mBatteryStatsService.scheduleWriteToDisk();
         mOnBattery = DEBUG_POWER ? true
@@ -2511,6 +2384,9 @@
 
         mUserController = new UserController(this);
 
+        mPendingIntentController = new PendingIntentController(
+                mHandlerThread.getLooper(), mUserController);
+
         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
 
@@ -2519,7 +2395,6 @@
         }
 
         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
-        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
 
         mActivityTaskManager = atm;
@@ -2597,6 +2472,7 @@
         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
         mActivityTaskManager.onActivityManagerInternalAdded();
         mUgmInternal.onActivityManagerInternalAdded();
+        mPendingIntentController.onActivityManagerInternalAdded();
         // Wait for the synchronized block started in mProcessCpuThread,
         // so that any other access to mProcessCpuTracker from main thread
         // will be blocked during mProcessCpuTracker initialization.
@@ -3455,16 +3331,8 @@
                 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;
-                }
+            if (mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
+                uid = 0;
             }
             int runtimeFlags = 0;
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
@@ -3648,6 +3516,9 @@
             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");
@@ -3657,12 +3528,14 @@
                         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!");
@@ -3791,102 +3664,35 @@
         return true;
     }
 
-    void updateUsageStats(ActivityRecord component, boolean resumed) {
+    void updateUsageStats(ComponentName activity, int uid, int userId, boolean resumed) {
         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
-                "updateUsageStats: comp=" + component + "res=" + resumed);
+                "updateUsageStats: comp=" + activity + "res=" + resumed);
         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
         StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
-            component.app.mUid, component.realActivity.getPackageName(),
-            component.realActivity.getShortClassName(), resumed ?
+            uid, activity.getPackageName(),
+            activity.getShortClassName(), resumed ?
                         StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
                         StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
         if (resumed) {
             if (mUsageStatsService != null) {
-                mUsageStatsService.reportEvent(component.realActivity, component.userId,
+                mUsageStatsService.reportEvent(activity, userId,
                         UsageEvents.Event.MOVE_TO_FOREGROUND);
 
             }
             synchronized (stats) {
-                stats.noteActivityResumedLocked(component.app.mUid);
+                stats.noteActivityResumedLocked(uid);
             }
         } else {
             if (mUsageStatsService != null) {
-                mUsageStatsService.reportEvent(component.realActivity, component.userId,
+                mUsageStatsService.reportEvent(activity, userId,
                         UsageEvents.Event.MOVE_TO_BACKGROUND);
             }
             synchronized (stats) {
-                stats.noteActivityPausedLocked(component.app.mUid);
+                stats.noteActivityPausedLocked(uid);
             }
         }
     }
 
-    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;
     }
@@ -3895,8 +3701,8 @@
         mCheckedForSetup = checked;
     }
 
-    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
-        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
+    CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
+        return mAtmInternal.compatibilityInfoForPackage(ai);
     }
 
     private void enforceNotIsolatedCaller(String caller) {
@@ -3906,37 +3712,8 @@
     }
 
     @Override
-    public int getPackageScreenCompatMode(String packageName) {
-        enforceNotIsolatedCaller("getPackageScreenCompatMode");
-        synchronized (this) {
-            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
-        }
-    }
-
-    @Override
     public void setPackageScreenCompatMode(String packageName, int mode) {
-        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
-                "setPackageScreenCompatMode");
-        synchronized (this) {
-            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
-        }
-    }
-
-    @Override
-    public boolean getPackageAskScreenCompat(String packageName) {
-        enforceNotIsolatedCaller("getPackageAskScreenCompat");
-        synchronized (this) {
-            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
-        }
-    }
-
-    @Override
-    public void setPackageAskScreenCompat(String packageName, boolean ask) {
-        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
-                "setPackageAskScreenCompat");
-        synchronized (this) {
-            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
-        }
+        mActivityTaskManager.setPackageScreenCompatMode(packageName, mode);
     }
 
     private boolean hasUsageStatsPermission(String callingPackage) {
@@ -4307,19 +4084,7 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-
-        synchronized(this) {
-            final ProcessRecord proc = mHeavyWeightProcess;
-            if (proc == null) {
-                return;
-            }
-
-            proc.getWindowProcessController().finishActivities();
-
-            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
-                    proc.userId, 0));
-            mHeavyWeightProcess = null;
-        }
+        mAtmInternal.finishHeavyWeightApp();
     }
 
     @Override
@@ -4349,7 +4114,6 @@
     private final void handleAppDiedLocked(ProcessRecord app,
             boolean restarting, boolean allowRestart) {
         int pid = app.pid;
-        final boolean clearLaunchStartTime = !restarting && app.removed && app.foregroundActivities;
         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
                 false /*replacingPid*/);
         if (!kept && !restarting) {
@@ -4390,18 +4154,6 @@
             mWindowManager.continueSurfaceLayout();
         }
 
-        // TODO (b/67683350)
-        // When an app process is removed, activities from the process may be relaunched. In the
-        // case of forceStopPackageLocked the activities are finished before any window is drawn,
-        // and the launch time is not cleared. This will be incorrectly used to calculate launch
-        // time for the next launched activity launched in the same windowing mode.
-        if (clearLaunchStartTime) {
-            final LaunchTimeTracker.Entry entry = mStackSupervisor
-                    .getLaunchTimeTracker().getEntry(mStackSupervisor.getWindowingMode());
-            if (entry != null) {
-                entry.mLaunchStartTime = 0;
-            }
-        }
     }
 
     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
@@ -5641,55 +5393,8 @@
         }
 
         if (packageName == null || uninstalling) {
-            // Remove pending intents.  For now we only do this when force
-            // stopping users, because we have some problems when doing this
-            // for packages -- app widgets are not currently cleaned up for
-            // such packages, so they can be left with bad pending intents.
-            if (mIntentSenderRecords.size() > 0) {
-                Iterator<WeakReference<PendingIntentRecord>> it
-                        = mIntentSenderRecords.values().iterator();
-                while (it.hasNext()) {
-                    WeakReference<PendingIntentRecord> wpir = it.next();
-                    if (wpir == null) {
-                        it.remove();
-                        continue;
-                    }
-                    PendingIntentRecord pir = wpir.get();
-                    if (pir == null) {
-                        it.remove();
-                        continue;
-                    }
-                    if (packageName == null) {
-                        // Stopping user, remove all objects for the user.
-                        if (pir.key.userId != userId) {
-                            // Not the same user, skip it.
-                            continue;
-                        }
-                    } else {
-                        if (UserHandle.getAppId(pir.uid) != appId) {
-                            // Different app id, skip it.
-                            continue;
-                        }
-                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
-                            // Different user, skip it.
-                            continue;
-                        }
-                        if (!pir.key.packageName.equals(packageName)) {
-                            // Different package, skip it.
-                            continue;
-                        }
-                    }
-                    if (!doit) {
-                        return true;
-                    }
-                    didSomething = true;
-                    it.remove();
-                    makeIntentSenderCanceledLocked(pir);
-                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
-                        pir.key.activity.pendingResults.remove(pir.ref);
-                    }
-                }
-            }
+            didSomething |= mPendingIntentController.removePendingIntentsForPackage(
+                    packageName, userId, appId, doit);
         }
 
         if (doit) {
@@ -5789,11 +5494,8 @@
             return false;
         }
         removeProcessNameLocked(name, uid);
-        if (mHeavyWeightProcess == app) {
-            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
-                    mHeavyWeightProcess.userId, 0));
-            mHeavyWeightProcess = null;
-        }
+        mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
+
         boolean needRestart = false;
         if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
             int pid = app.pid;
@@ -5851,11 +5553,7 @@
             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
                     pid, app.uid, app.processName);
             removeProcessNameLocked(app.processName, app.uid);
-            if (mHeavyWeightProcess == app) {
-                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
-                        mHeavyWeightProcess.userId, 0));
-                mHeavyWeightProcess = null;
-            }
+            mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
             // Take care of any launching providers waiting for this process.
             cleanupAppInLaunchingProvidersLocked(app, true);
@@ -6032,9 +5730,10 @@
                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
             }
             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
-                    + processName + " with config " + getGlobalConfiguration());
+                    + processName + " with config "
+                    + app.getWindowProcessController().getConfiguration());
             ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info;
-            app.compat = compatibilityInfoForPackageLocked(appInfo);
+            app.compat = compatibilityInfoForPackage(appInfo);
 
             ProfilerInfo profilerInfo = null;
             String preBindAgent = null;
@@ -6145,8 +5844,8 @@
                         instr2.mUiAutomationConnection, testMode,
                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
                         isRestrictedBackupMode || !normalMode, app.isPersistent(),
-                        new Configuration(getGlobalConfiguration()), app.compat,
-                        getCommonServicesLocked(app.isolated),
+                        new Configuration(app.getWindowProcessController().getConfiguration()),
+                        app.compat, getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
                         buildSerial, isAutofillCompatEnabled);
             } else {
@@ -6154,8 +5853,8 @@
                         null, null, null, testMode,
                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
                         isRestrictedBackupMode || !normalMode, app.isPersistent(),
-                        new Configuration(getGlobalConfiguration()), app.compat,
-                        getCommonServicesLocked(app.isolated),
+                        new Configuration(app.getWindowProcessController().getConfiguration()),
+                        app.compat, getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
                         buildSerial, isAutofillCompatEnabled);
             }
@@ -6231,7 +5930,7 @@
                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
             try {
                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
-                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
+                        compatibilityInfoForPackage(mBackupTarget.appInfo),
                         mBackupTarget.backupMode);
             } catch (Exception e) {
                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
@@ -6264,11 +5963,6 @@
         }
     }
 
-    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
-        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
-                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
-    }
-
     @Override
     public void showBootMessage(final CharSequence msg, final boolean always) {
         if (Binder.getCallingUid() != myUid()) {
@@ -6278,6 +5972,8 @@
     }
 
     final void finishBooting() {
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
+
         synchronized (this) {
             if (!mBootAnimationComplete) {
                 mCallFinishBooting = true;
@@ -6383,6 +6079,8 @@
                     });
             mUserController.scheduleStartProfiles();
         }
+
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
     @Override
@@ -6393,9 +6091,7 @@
             mBootAnimationComplete = true;
         }
         if (callFinishBooting) {
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
             finishBooting();
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -6410,9 +6106,7 @@
         }
 
         if (booting) {
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
             finishBooting();
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
 
         if (enableScreen) {
@@ -6483,90 +6177,19 @@
                     }
                 }
 
-                return getIntentSenderLocked(type, packageName, callingUid, userId,
-                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
-
+                if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
+                    return mAtmInternal.getIntentSender(type, packageName, callingUid, userId,
+                            token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
+                }
+                return mPendingIntentController.getIntentSender(type, packageName, callingUid,
+                        userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
+                        bOptions);
             } catch (RemoteException e) {
                 throw new SecurityException(e);
             }
         }
     }
 
-    IIntentSender getIntentSenderLocked(int type, String packageName,
-            int callingUid, int userId, IBinder token, String resultWho,
-            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
-            Bundle bOptions) {
-        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
-        ActivityRecord activity = null;
-        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
-            activity = ActivityRecord.isInStackLocked(token);
-            if (activity == null) {
-                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
-                return null;
-            }
-            if (activity.finishing) {
-                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
-                return null;
-            }
-        }
-
-        // We're going to be splicing together extras before sending, so we're
-        // okay poking into any contained extras.
-        if (intents != null) {
-            for (int i = 0; i < intents.length; i++) {
-                intents[i].setDefusable(true);
-            }
-        }
-        Bundle.setDefusable(bOptions, true);
-
-        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
-        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
-        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
-        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
-                |PendingIntent.FLAG_UPDATE_CURRENT);
-
-        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
-                resultWho, requestCode, intents, resolvedTypes, flags,
-                SafeActivityOptions.fromBundle(bOptions), userId);
-        WeakReference<PendingIntentRecord> ref;
-        ref = mIntentSenderRecords.get(key);
-        PendingIntentRecord rec = ref != null ? ref.get() : null;
-        if (rec != null) {
-            if (!cancelCurrent) {
-                if (updateCurrent) {
-                    if (rec.key.requestIntent != null) {
-                        rec.key.requestIntent.replaceExtras(intents != null ?
-                                intents[intents.length - 1] : null);
-                    }
-                    if (intents != null) {
-                        intents[intents.length-1] = rec.key.requestIntent;
-                        rec.key.allIntents = intents;
-                        rec.key.allResolvedTypes = resolvedTypes;
-                    } else {
-                        rec.key.allIntents = null;
-                        rec.key.allResolvedTypes = null;
-                    }
-                }
-                return rec;
-            }
-            makeIntentSenderCanceledLocked(rec);
-            mIntentSenderRecords.remove(key);
-        }
-        if (noCreate) {
-            return rec;
-        }
-        rec = new PendingIntentRecord(this, key, callingUid);
-        mIntentSenderRecords.put(key, rec.ref);
-        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
-            if (activity.pendingResults == null) {
-                activity.pendingResults
-                        = new HashSet<WeakReference<PendingIntentRecord>>();
-            }
-            activity.pendingResults.add(rec.ref);
-        }
-        return rec;
-    }
-
     @Override
     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
             Intent intent, String resolvedType,
@@ -6606,44 +6229,7 @@
 
     @Override
     public void cancelIntentSender(IIntentSender sender) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        synchronized(this) {
-            PendingIntentRecord rec = (PendingIntentRecord)sender;
-            try {
-                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
-                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
-                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
-                    String msg = "Permission Denial: cancelIntentSender() from pid="
-                        + Binder.getCallingPid()
-                        + ", uid=" + Binder.getCallingUid()
-                        + " is not allowed to cancel package "
-                        + rec.key.packageName;
-                    Slog.w(TAG, msg);
-                    throw new SecurityException(msg);
-                }
-            } catch (RemoteException e) {
-                throw new SecurityException(e);
-            }
-            cancelIntentSenderLocked(rec, true);
-        }
-    }
-
-    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
-        makeIntentSenderCanceledLocked(rec);
-        mIntentSenderRecords.remove(rec.key);
-        if (cleanActivity && rec.key.activity != null) {
-            rec.key.activity.pendingResults.remove(rec.ref);
-        }
-    }
-
-    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
-        rec.canceled = true;
-        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
-        if (callbacks != null) {
-            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
-        }
+        mPendingIntentController.cancelIntentSender(sender);
     }
 
     @Override
@@ -7038,7 +6624,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;
@@ -7954,7 +7540,28 @@
                 }
             }
 
-            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
+            boolean providerRunning = false;
+
+            if (cpr != null && cpr.proc != null) {
+                providerRunning = !cpr.proc.killed;
+
+                // Note if killedByAm is also set, this means the provider process has just been
+                // killed by AM (in ProcessRecord.kill()), but appDiedLocked() hasn't been called
+                // yet. So we need to call appDiedLocked() here and let it clean up.
+                // (See the commit message on I2c4ba1e87c2d47f2013befff10c49b3dc337a9a7 to see
+                // how to test this case.)
+                if (cpr.proc.killed && cpr.proc.killedByAm) {
+                    checkTime(startTime, "getContentProviderImpl: before appDied (killedByAm)");
+                    final long iden = Binder.clearCallingIdentity();
+                    try {
+                        appDiedLocked(cpr.proc);
+                    } finally {
+                        Binder.restoreCallingIdentity(iden);
+                    }
+                    checkTime(startTime, "getContentProviderImpl: after appDied (killedByAm)");
+                }
+            }
+
             if (providerRunning) {
                 cpi = cpr.info;
                 String msg;
@@ -8406,10 +8013,17 @@
         }
     }
 
+    /** @deprecated - Use {@link #removeContentProviderExternalAsUser} which takes a user ID. */
+    @Deprecated
+    @Override
     public void removeContentProviderExternal(String name, IBinder token) {
+        removeContentProviderExternalAsUser(name, token, UserHandle.getCallingUserId());
+    }
+
+    @Override
+    public void removeContentProviderExternalAsUser(String name, IBinder token, int userId) {
         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
             "Do not have permission in call removeContentProviderExternal()");
-        int userId = UserHandle.getCallingUserId();
         long ident = Binder.clearCallingIdentity();
         try {
             removeContentProviderExternalUnchecked(name, token, userId);
@@ -8853,7 +8467,7 @@
             StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
                     StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
         }
-        final ProcessRecord r = new ProcessRecord(this, info, proc, uid);
+        final ProcessRecord r = new ProcessRecord(this, info, proc, uid, getGlobalConfiguration());
         if (!mBooted && !mBooting
                 && userId == UserHandle.USER_SYSTEM
                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
@@ -9097,7 +8711,7 @@
                     if (mActivityTaskManager.mKeyguardController.isKeyguardLocked()) {
                         // Showing launcher to avoid user entering credential twice.
                         final int currentUserId = mUserController.getCurrentUserId();
-                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
+                        mAtmInternal.startHomeActivity(currentUserId, "notifyLockedProfile");
                     }
                     mStackSupervisor.lockAllProfileTasks(userId);
                 }
@@ -9120,7 +8734,7 @@
                         ? new ActivityOptions(options)
                         : ActivityOptions.makeBasic();
                 activityOptions.setLaunchTaskId(
-                        mStackSupervisor.getHomeActivity().getTask().taskId);
+                        mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
                 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
                         UserHandle.CURRENT);
             } finally {
@@ -9741,9 +9355,10 @@
 
         mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
         if (workSource != null) {
-            StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, workSource, tag);
+            StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, workSource, tag, sourcePkg);
         } else {
-            StatsLog.write_non_chained(StatsLog.WAKEUP_ALARM_OCCURRED, sourceUid, null, tag);
+            StatsLog.write_non_chained(StatsLog.WAKEUP_ALARM_OCCURRED, sourceUid, null, tag,
+                    sourcePkg);
         }
     }
 
@@ -10109,8 +9724,6 @@
                 return;
             }
 
-            mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_CANT_SAVE_STATE);
             mLocalDeviceIdleController
                     = LocalServices.getService(DeviceIdleController.LocalService.class);
             mActivityTaskManager.onSystemReady();
@@ -10155,44 +9768,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();
@@ -10238,7 +9816,7 @@
                     throw e.rethrowAsRuntimeException();
                 }
             }
-            startHomeActivityLocked(currentUserId, "systemReady");
+            mAtmInternal.startHomeActivity(currentUserId, "systemReady");
 
             mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
 
@@ -10845,7 +10423,7 @@
             int clientTargetSdk) {
         outInfo.pid = app.pid;
         outInfo.uid = app.info.uid;
-        if (mHeavyWeightProcess == app) {
+        if (mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
         }
         if (app.isPersistent()) {
@@ -10898,9 +10476,13 @@
                         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();
+                    } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
+                        ActivityServiceConnectionsHolder r =
+                                (ActivityServiceConnectionsHolder) app.adjSource;
+                        final int pid = r.getActivityPid();
+                        if (pid != -1) {
+                            currApp.importanceReasonPid = pid;
+                        }
                     }
                     if (app.adjTarget instanceof ComponentName) {
                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
@@ -11000,7 +10582,7 @@
                 pw.println("-------------------------------------------------------------------------------");
 
             }
-            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+            mPendingIntentController.dumpPendingIntents(pw, dumpAll, dumpPackage);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
@@ -11293,7 +10875,7 @@
                     opti++;
                 }
                 synchronized (this) {
-                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
+                    mPendingIntentController.dumpPendingIntents(pw, true, dumpPackage);
                 }
             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
                 if (opti < args.length) {
@@ -11888,13 +11470,13 @@
             TimeUtils.formatDuration(mActivityTaskManager.mPreviousProcessVisibleTime, sb);
             pw.println(sb);
         }
-        if (mHeavyWeightProcess != null && (dumpPackage == null
-                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
+        if (mActivityTaskManager.mHeavyWeightProcess != null && (dumpPackage == null
+                || mActivityTaskManager.mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
             if (needSep) {
                 pw.println();
                 needSep = false;
             }
-            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
+            pw.println("  mHeavyWeightProcess: " + mActivityTaskManager.mHeavyWeightProcess);
         }
         if (dumpAll && mPendingStarts.size() > 0) {
             if (needSep) pw.println();
@@ -11913,10 +11495,10 @@
                 pw.println("  mConfigWillChange: "
                         + mActivityTaskManager.getTopDisplayFocusedStack().mConfigWillChange);
             }
-            if (mCompatModePackages.getPackages().size() > 0) {
+            if (mActivityTaskManager.mCompatModePackages.getPackages().size() > 0) {
                 boolean printed = false;
                 for (Map.Entry<String, Integer> entry
-                        : mCompatModePackages.getPackages().entrySet()) {
+                        : mActivityTaskManager.mCompatModePackages.getPackages().entrySet()) {
                     String pkg = entry.getKey();
                     int mode = entry.getValue();
                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
@@ -12298,12 +11880,13 @@
             proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mActivityTaskManager.mPreviousProcessVisibleTime);
         }
 
-        if (mHeavyWeightProcess != null && (dumpPackage == null
-                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
-            mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
+        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 : mCompatModePackages.getPackages().entrySet()) {
+        for (Map.Entry<String, Integer> entry
+                : mActivityTaskManager.mCompatModePackages.getPackages().entrySet()) {
             String pkg = entry.getKey();
             int mode = entry.getValue();
             if (dumpPackage == null || dumpPackage.equals(pkg)) {
@@ -12556,8 +12139,8 @@
         pw.println();
         pw.println("  mHomeProcess: " + mActivityTaskManager.mHomeProcess);
         pw.println("  mPreviousProcess: " + mActivityTaskManager.mPreviousProcess);
-        if (mHeavyWeightProcess != null) {
-            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
+        if (mActivityTaskManager.mHeavyWeightProcess != null) {
+            pw.println("  mHeavyWeightProcess: " + mActivityTaskManager.mHeavyWeightProcess);
         }
 
         return true;
@@ -12990,61 +12573,6 @@
         mUgmInternal.dump(pw, dumpAll, dumpPackage);
     }
 
-    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll, String dumpPackage) {
-        boolean printed = false;
-
-        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
-
-        if (mIntentSenderRecords.size() > 0) {
-            // Organize these by package name, so they are easier to read.
-            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
-            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
-            final Iterator<WeakReference<PendingIntentRecord>> it
-                    = mIntentSenderRecords.values().iterator();
-            while (it.hasNext()) {
-                WeakReference<PendingIntentRecord> ref = it.next();
-                PendingIntentRecord rec = ref != null ? ref.get() : null;
-                if (rec == null) {
-                    weakRefs.add(ref);
-                    continue;
-                }
-                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
-                    continue;
-                }
-                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
-                if (list == null) {
-                    list = new ArrayList<>();
-                    byPackage.put(rec.key.packageName, list);
-                }
-                list.add(rec);
-            }
-            for (int i = 0; i < byPackage.size(); i++) {
-                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
-                printed = true;
-                pw.print("  * "); pw.print(byPackage.keyAt(i));
-                pw.print(": "); pw.print(intents.size()); pw.println(" items");
-                for (int j = 0; j < intents.size(); j++) {
-                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
-                    if (dumpAll) {
-                        intents.get(j).dump(pw, "      ");
-                    }
-                }
-            }
-            if (weakRefs.size() > 0) {
-                printed = true;
-                pw.println("  * WEAK REFS:");
-                for (int i = 0; i < weakRefs.size(); i++) {
-                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
-                }
-            }
-        }
-
-        if (!printed) {
-            pw.println("  (nothing)");
-        }
-    }
-
     private static final int dumpProcessList(PrintWriter pw,
             ActivityManagerService service, List list,
             String prefix, String normalLabel, String persistentLabel,
@@ -15189,11 +14717,7 @@
             if (!replacingPid) {
                 removeProcessNameLocked(app.processName, app.uid, app);
             }
-            if (mHeavyWeightProcess == app) {
-                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
-                        mHeavyWeightProcess.userId, 0));
-                mHeavyWeightProcess = null;
-            }
+            mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
         } else if (!app.removed) {
             // This app is persistent, so we need to keep its record around.
             // If it is not already on the pending app list, add it there
@@ -15323,24 +14847,6 @@
         }
     }
 
-    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
-            boolean fgRequired, String callingPackage, int userId)
-            throws TransactionTooLargeException {
-        synchronized(this) {
-            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
-                    "startServiceInPackage: " + service + " type=" + resolvedType);
-            final long origId = Binder.clearCallingIdentity();
-            ComponentName res;
-            try {
-                res = mServices.startServiceLocked(null, service,
-                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-            return res;
-        }
-    }
-
     @Override
     public int stopService(IApplicationThread caller, Intent service,
             String resolvedType, int userId) {
@@ -15577,7 +15083,7 @@
                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
                 try {
                     proc.thread.scheduleCreateBackupAgent(app,
-                            compatibilityInfoForPackageLocked(app), backupMode);
+                            compatibilityInfoForPackage(app), backupMode);
                 } catch (RemoteException e) {
                     // Will time out on the backup manager side
                 }
@@ -15676,7 +15182,7 @@
                 if (proc.thread != null) {
                     try {
                         proc.thread.scheduleDestroyBackupAgent(appInfo,
-                                compatibilityInfoForPackageLocked(appInfo));
+                                compatibilityInfoForPackage(appInfo));
                     } catch (Exception e) {
                         Slog.e(TAG, "Exception when unbinding backup agent:");
                         e.printStackTrace();
@@ -16385,7 +15891,6 @@
 
                                         mServices.forceStopPackageLocked(ssp, userId);
                                         mAtmInternal.onPackageUninstalled(ssp);
-                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
                                         mBatteryStatsService.notePackageUninstalled(ssp);
                                     }
                                 } else {
@@ -16447,7 +15952,7 @@
                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                         final boolean replacing =
                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
-                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
+                        mAtmInternal.onPackageAdded(ssp, replacing);
 
                         try {
                             ApplicationInfo ai = AppGlobals.getPackageManager().
@@ -16464,7 +15969,6 @@
                     Uri data = intent.getData();
                     String ssp;
                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
-                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
                         mAtmInternal.onPackageDataCleared(ssp);
                     }
                     break;
@@ -17222,30 +16726,6 @@
         }
     }
 
-    // =========================================================
-    // CONFIGURATION
-    // =========================================================
-
-    public ConfigurationInfo getDeviceConfigurationInfo() {
-        ConfigurationInfo config = new ConfigurationInfo();
-        synchronized (this) {
-            final Configuration globalConfig = getGlobalConfiguration();
-            config.reqTouchScreen = globalConfig.touchscreen;
-            config.reqKeyboardType = globalConfig.keyboard;
-            config.reqNavigation = globalConfig.navigation;
-            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
-                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
-                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
-            }
-            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
-                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
-                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
-            }
-            config.reqGlEsVersion = GL_ES_VERSION;
-        }
-        return config;
-    }
-
     @Override
     public StackInfo getFocusedStackInfo() throws RemoteException {
         return mActivityTaskManager.getFocusedStackInfo();
@@ -17809,7 +17289,7 @@
             }
         }
 
-        if (app == mHeavyWeightProcess) {
+        if (mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                 // We don't want to kill the current heavy-weight process.
                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
@@ -18177,10 +17657,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) {
@@ -21055,7 +20535,8 @@
                                     memoryStat.pgmajfault,
                                     memoryStat.rssInBytes,
                                     memoryStat.cacheInBytes,
-                                    memoryStat.swapInBytes);
+                                    memoryStat.swapInBytes,
+                                    memoryStat.rssHighWatermarkInBytes);
                     processMemoryStates.add(processMemoryState);
                 }
             }
@@ -21090,18 +20571,6 @@
             ActivityManagerService.this.trimApplications();
         }
 
-        public int getPackageScreenCompatMode(ApplicationInfo ai) {
-            synchronized (ActivityManagerService.this) {
-                return mCompatModePackages.computeCompatModeLocked(ai);
-            }
-        }
-
-        public void setPackageScreenCompatMode(ApplicationInfo ai, int mode) {
-            synchronized (ActivityManagerService.this) {
-                mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
-            }
-        }
-
         public void closeSystemDialogs(String reason) {
             ActivityManagerService.this.closeSystemDialogs(reason);
         }
@@ -21150,6 +20619,38 @@
         }
 
         @Override
+        public void updateCpuStats() {
+            synchronized (ActivityManagerService.this) {
+                ActivityManagerService.this.updateCpuStats();
+            }
+        }
+
+        @Override
+        public void updateUsageStats(ComponentName activity, int uid, int userId, boolean resumed) {
+            synchronized (ActivityManagerService.this) {
+                ActivityManagerService.this.updateUsageStats(activity, uid, userId, resumed);
+            }
+        }
+
+        @Override
+        public void updateForegroundTimeIfOnBattery(
+                String packageName, int uid, long cpuTimeDiff) {
+            synchronized (ActivityManagerService.this) {
+                if (!mBatteryStatsService.isOnBattery()) {
+                    return;
+                }
+                final BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
+                synchronized (bsi) {
+                    final BatteryStatsImpl.Uid.Proc ps =
+                            bsi.getProcessStatsLocked(uid, packageName);
+                    if (ps != null) {
+                        ps.addForegroundTimeLocked(cpuTimeDiff);
+                    }
+                }
+            }
+        }
+
+        @Override
         public void sendForegroundProfileChanged(int userId) {
             mUserController.sendForegroundProfileChanged(userId);
         }
@@ -21190,13 +20691,6 @@
         }
 
         @Override
-        public Intent getHomeIntent() {
-            synchronized (ActivityManagerService.this) {
-                return ActivityManagerService.this.getHomeIntent();
-            }
-        }
-
-        @Override
         public void scheduleAppGcs() {
             synchronized (ActivityManagerService.this) {
                 ActivityManagerService.this.scheduleAppGcsLocked();
@@ -21209,6 +20703,81 @@
                 return ActivityManagerService.this.getTaskForActivity(token, onlyRoot);
             }
         }
+
+        @Override
+        public void setBooting(boolean booting) {
+            mBooting = booting;
+        }
+
+        @Override
+        public boolean isBooting() {
+            return mBooting;
+        }
+
+        @Override
+        public void setBooted(boolean booted) {
+            mBooted = booted;
+        }
+
+        @Override
+        public boolean isBooted() {
+            return mBooted;
+        }
+
+        @Override
+        public void finishBooting() {
+            ActivityManagerService.this.finishBooting();
+        }
+
+        @Override
+        public void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid,
+                long duration, String tag) {
+            synchronized (ActivityManagerService.this) {
+                ActivityManagerService.this.tempWhitelistForPendingIntentLocked(
+                        callerPid, callerUid, targetUid, duration, tag);
+            }
+        }
+
+        @Override
+        public int broadcastIntentInPackage(String packageName, int uid, Intent intent,
+                String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData,
+                Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized,
+                boolean sticky, int userId) {
+            synchronized (ActivityManagerService.this) {
+                return ActivityManagerService.this.broadcastIntentInPackage(packageName, uid,
+                        intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
+                        requiredPermission, bOptions, serialized, sticky, userId);
+            }
+        }
+
+        @Override
+        public ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
+                boolean fgRequired, String callingPackage, int userId)
+                throws TransactionTooLargeException {
+            synchronized(ActivityManagerService.this) {
+                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
+                        "startServiceInPackage: " + service + " type=" + resolvedType);
+                final long origId = Binder.clearCallingIdentity();
+                ComponentName res;
+                try {
+                    res = mServices.startServiceLocked(null, service,
+                            resolvedType, -1, uid, fgRequired, callingPackage, userId);
+                } finally {
+                    Binder.restoreCallingIdentity(origId);
+                }
+                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));
+            }
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index b24c36a..40c555f8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -568,9 +568,6 @@
                 if (result.who != null) {
                     pw.println("Activity: " + result.who.flattenToShortString());
                 }
-                if (result.thisTime >= 0) {
-                    pw.println("ThisTime: " + result.thisTime);
-                }
                 if (result.totalTime >= 0) {
                     pw.println("TotalTime: " + result.totalTime);
                 }
@@ -2063,7 +2060,12 @@
             pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
         }
 
-        ConfigurationInfo configInfo = mInternal.getDeviceConfigurationInfo();
+        ConfigurationInfo configInfo = null;
+        try {
+            configInfo = mTaskInterface.getDeviceConfigurationInfo();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
         if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
             if (protoOutputStream != null) {
                 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 263c34f..18cdb05 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -3,13 +3,13 @@
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.ActivityManager.processStateAmToProto;
-import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 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_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_ACTIVITY_START;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
@@ -28,9 +28,9 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME;
@@ -57,16 +57,16 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PENDING_UI_CLEAN;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PROCESS_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_HOT_LAUNCH;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
@@ -75,8 +75,10 @@
 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.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
 import static com.android.server.am.MemoryStatUtil.MemoryStat;
 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
 
 import android.content.Context;
 import android.content.Intent;
@@ -88,20 +90,27 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
+import android.os.Trace;
+import android.util.EventLog;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.StatsLog;
+import android.util.TimeUtils;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.SomeArgs;
 import com.android.server.LocalServices;
 
-import java.util.ArrayList;
-
 /**
- * Handles logging into Tron.
+ * Listens to activity launches, transitions, visibility changes and window drawn callbacks to
+ * determine app launch times and draw delays. Source of truth for activity metrics and provides
+ * data for Tron, logcat, event logs and {@link android.app.WaitResult}.
+ *
+ * Tests:
+ * atest SystemMetricsFunctionalTests
  */
 class ActivityMetricsLogger {
 
@@ -116,6 +125,8 @@
     private static final int WINDOW_STATE_INVALID = -1;
 
     private static final long INVALID_START_TIME = -1;
+    private static final int INVALID_DELAY = -1;
+    private static final int INVALID_TRANSITION_TYPE = -1;
 
     private static final int MSG_CHECK_VISIBILITY = 0;
 
@@ -144,6 +155,8 @@
     private final H mHandler;
 
     private ArtManagerInternal mArtManagerInternal;
+    private boolean mDrawingTraceActive;
+    private final StringBuilder mStringBuilder = new StringBuilder();
 
     private final class H extends Handler {
 
@@ -166,36 +179,56 @@
         private ActivityRecord launchedActivity;
         private int startResult;
         private boolean currentTransitionProcessRunning;
+        /** Elapsed time from when we launch an activity to when its windows are drawn. */
         private int windowsDrawnDelayMs;
-        private int startingWindowDelayMs = -1;
-        private int bindApplicationDelayMs = -1;
+        private int startingWindowDelayMs = INVALID_DELAY;
+        private int bindApplicationDelayMs = INVALID_DELAY;
         private int reason = APP_TRANSITION_TIMEOUT;
         private boolean loggedWindowsDrawn;
         private boolean loggedStartingWindowDrawn;
+        private boolean launchTraceActive;
     }
 
-    private final class WindowingModeTransitionInfoSnapshot {
+    final class WindowingModeTransitionInfoSnapshot {
         final private ApplicationInfo applicationInfo;
         final private WindowProcessController processRecord;
-        final private String packageName;
-        final private String launchedActivityName;
+        final String packageName;
+        final String launchedActivityName;
         final private String launchedActivityLaunchedFromPackage;
         final private String launchedActivityLaunchToken;
         final private String launchedActivityAppRecordRequiredAbi;
+        final String launchedActivityShortComponentName;
         final private String processName;
         final private int reason;
         final private int startingWindowDelayMs;
         final private int bindApplicationDelayMs;
-        final private int windowsDrawnDelayMs;
-        final private int type;
+        final int windowsDrawnDelayMs;
+        final int type;
+        final int userId;
+        /**
+         * Elapsed time from when we launch an activity to when the app reported it was
+         * fully drawn. If this is not reported then the value is set to INVALID_DELAY.
+         */
+        final int windowsFullyDrawnDelayMs;
+        final int activityRecordIdHashCode;
 
         private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info) {
-            applicationInfo = info.launchedActivity.appInfo;
-            packageName = info.launchedActivity.packageName;
-            launchedActivityName = info.launchedActivity.info.name;
-            launchedActivityLaunchedFromPackage = info.launchedActivity.launchedFromPackage;
-            launchedActivityLaunchToken = info.launchedActivity.info.launchToken;
-            launchedActivityAppRecordRequiredAbi = info.launchedActivity.app == null
+            this(info, info.launchedActivity);
+        }
+
+        private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
+                ActivityRecord launchedActivity) {
+            this(info, launchedActivity, INVALID_DELAY);
+        }
+
+        private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
+                ActivityRecord launchedActivity, int windowsFullyDrawnDelayMs) {
+            applicationInfo = launchedActivity.appInfo;
+            packageName = launchedActivity.packageName;
+            launchedActivityName = launchedActivity.info.name;
+            launchedActivityLaunchedFromPackage = launchedActivity.launchedFromPackage;
+            launchedActivityLaunchToken = launchedActivity.info.launchToken;
+            launchedActivityAppRecordRequiredAbi = launchedActivity.app == null
                     ? null
                     : info.launchedActivity.app.getRequiredAbi();
             reason = info.reason;
@@ -205,6 +238,10 @@
             type = getTransitionType(info);
             processRecord = findProcessForActivity(info.launchedActivity);
             processName = info.launchedActivity.processName;
+            userId = launchedActivity.userId;
+            launchedActivityShortComponentName = launchedActivity.shortComponentName;
+            activityRecordIdHashCode = System.identityHashCode(launchedActivity);
+            this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs;
         }
     }
 
@@ -336,7 +373,7 @@
                 || 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 */);
+            reset(true /* abort */, info);
             return;
         } else if (otherWindowModesLaunching) {
             // Don't log this windowing mode but continue with the other windowing modes.
@@ -352,6 +389,7 @@
         mWindowingModeTransitionInfo.put(windowingMode, newInfo);
         mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
         mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
+        startTraces(newInfo);
     }
 
     /**
@@ -365,18 +403,21 @@
     /**
      * Notifies the tracker that all windows of the app have been drawn.
      */
-    void notifyWindowsDrawn(int windowingMode, long timestamp) {
+    WindowingModeTransitionInfoSnapshot notifyWindowsDrawn(int windowingMode, long timestamp) {
         if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
 
         final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
         if (info == null || info.loggedWindowsDrawn) {
-            return;
+            return null;
         }
         info.windowsDrawnDelayMs = calculateDelay(timestamp);
         info.loggedWindowsDrawn = true;
+        final WindowingModeTransitionInfoSnapshot infoSnapshot =
+                new WindowingModeTransitionInfoSnapshot(info);
         if (allWindowsDrawn() && mLoggedTransitionStarting) {
-            reset(false /* abort */);
+            reset(false /* abort */, info);
         }
+        return infoSnapshot;
     }
 
     /**
@@ -395,7 +436,7 @@
      * Notifies the tracker that the app transition is starting.
      *
      * @param windowingModeToReason A map from windowing mode to a reason integer, which must be on
-     *                              of ActivityManagerInternal.APP_TRANSITION_* reasons.
+     *                              of ActivityTaskManagerInternal.APP_TRANSITION_* reasons.
      */
     void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
         if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
@@ -414,7 +455,7 @@
             info.reason = windowingModeToReason.valueAt(index);
         }
         if (allWindowsDrawn()) {
-            reset(false /* abort */);
+            reset(false /* abort */, null /* WindowingModeTransitionInfo */);
         }
     }
 
@@ -453,8 +494,9 @@
                 logAppTransitionCancel(info);
                 mWindowingModeTransitionInfo.remove(r.getWindowingMode());
                 if (mWindowingModeTransitionInfo.size() == 0) {
-                    reset(true /* abort */);
+                    reset(true /* abort */, info);
                 }
+                stopFullyDrawnTraceIfNeeded();
             }
         }
     }
@@ -489,19 +531,19 @@
                 && mWindowingModeTransitionInfo.size() > 0;
     }
 
-    private void reset(boolean abort) {
+    private void reset(boolean abort, WindowingModeTransitionInfo info) {
         if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort);
         if (!abort && isAnyTransitionActive()) {
             logAppTransitionMultiEvents();
         }
+        stopLaunchTrace(info);
         mCurrentTransitionStartTime = INVALID_START_TIME;
-        mCurrentTransitionDelayMs = -1;
+        mCurrentTransitionDelayMs = INVALID_DELAY;
         mLoggedTransitionStarting = false;
         mWindowingModeTransitionInfo.clear();
     }
 
     private int calculateCurrentDelay() {
-
         // Shouldn't take more than 25 days to launch an app, so int is fine here.
         return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
     }
@@ -513,7 +555,7 @@
 
     private void logAppTransitionCancel(WindowingModeTransitionInfo info) {
         final int type = getTransitionType(info);
-        if (type == -1) {
+        if (type == INVALID_TRANSITION_TYPE) {
             return;
         }
         final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
@@ -534,7 +576,7 @@
         for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
             final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
             final int type = getTransitionType(info);
-            if (type == -1) {
+            if (type == INVALID_TRANSITION_TYPE) {
                 return;
             }
 
@@ -546,6 +588,7 @@
             final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
             BackgroundThread.getHandler().post(() -> logAppTransition(
                     currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
+            BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
 
             info.launchedActivity.info.launchToken = null;
         }
@@ -572,11 +615,11 @@
                 currentTransitionDeviceUptime);
         builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
         builder.setSubtype(info.reason);
-        if (info.startingWindowDelayMs != -1) {
+        if (info.startingWindowDelayMs != INVALID_DELAY) {
             builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
                     info.startingWindowDelayMs);
         }
-        if (info.bindApplicationDelayMs != -1) {
+        if (info.bindApplicationDelayMs != INVALID_DELAY) {
             builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
                     info.bindApplicationDelayMs);
         }
@@ -613,6 +656,24 @@
         logAppStartMemoryStateCapture(info);
     }
 
+    private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) {
+        if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
+            return;
+        }
+
+        EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
+                info.userId, info.activityRecordIdHashCode, info.launchedActivityShortComponentName,
+                info.windowsDrawnDelayMs);
+
+        StringBuilder sb = mStringBuilder;
+        sb.setLength(0);
+        sb.append("Displayed ");
+        sb.append(info.launchedActivityShortComponentName);
+        sb.append(": ");
+        TimeUtils.formatDuration(info.windowsDrawnDelayMs, sb);
+        Log.i(TAG, sb.toString());
+    }
+
     private int convertAppStartTransitionType(int tronType) {
         if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
             return StatsLog.APP_START_OCCURRED__TYPE__COLD;
@@ -626,11 +687,12 @@
         return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
      }
 
-    void logAppTransitionReportedDrawn(ActivityRecord r, boolean restoredFromBundle) {
+    WindowingModeTransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r,
+            boolean restoredFromBundle) {
         final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
                 r.getWindowingMode());
         if (info == null) {
-            return;
+            return null;
         }
         final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
         builder.setPackageName(r.packageName);
@@ -653,6 +715,25 @@
                 info.launchedActivity.info.name,
                 info.currentTransitionProcessRunning,
                 startupTimeMs);
+        stopFullyDrawnTraceIfNeeded();
+        final WindowingModeTransitionInfoSnapshot infoSnapshot =
+                new WindowingModeTransitionInfoSnapshot(info, r, (int) startupTimeMs);
+        BackgroundThread.getHandler().post(() -> logAppFullyDrawn(infoSnapshot));
+        return infoSnapshot;
+    }
+
+    private void logAppFullyDrawn(WindowingModeTransitionInfoSnapshot info) {
+        if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
+            return;
+        }
+
+        StringBuilder sb = mStringBuilder;
+        sb.setLength(0);
+        sb.append("Fully drawn ");
+        sb.append(info.launchedActivityShortComponentName);
+        sb.append(": ");
+        TimeUtils.formatDuration(info.windowsFullyDrawnDelayMs, sb);
+        Log.i(TAG, sb.toString());
     }
 
     void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r,
@@ -754,7 +835,7 @@
         } else if (info.startResult == START_SUCCESS) {
             return TYPE_TRANSITION_COLD_LAUNCH;
         }
-        return -1;
+        return INVALID_TRANSITION_TYPE;
     }
 
     private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
@@ -799,4 +880,46 @@
         }
         return mArtManagerInternal;
     }
+
+    /**
+     * 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()}
+     *
+     * @param info
+     * */
+    private void startTraces(WindowingModeTransitionInfo info) {
+        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;
+        }
+    }
+
+    private void stopLaunchTrace(WindowingModeTransitionInfo info) {
+        if (info == null) {
+            return;
+        }
+        if (info.launchTraceActive) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
+                    + info.launchedActivity.packageName, 0);
+            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 628207c..fe10baf 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -17,20 +17,21 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
 import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
 import static android.app.ActivityOptions.ANIM_CUSTOM;
+import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
 import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
 import static android.app.ActivityOptions.ANIM_SCALE_UP;
 import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
-import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
+import static android.app.WaitResult.INVALID_DELAY;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -80,7 +81,8 @@
 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.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+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;
@@ -93,6 +95,13 @@
 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.ActivityRecordProto.CONFIGURATION_CONTAINER;
+import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
+import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
+import static com.android.server.am.ActivityRecordProto.PROC_ID;
+import static com.android.server.am.ActivityRecordProto.STATE;
+import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
+import static com.android.server.am.ActivityRecordProto.VISIBLE;
 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
@@ -103,21 +112,11 @@
 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.EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME;
-import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
 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 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;
-import static com.android.server.am.ActivityRecordProto.PROC_ID;
-import static com.android.server.am.ActivityRecordProto.STATE;
-import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
-import static com.android.server.am.ActivityRecordProto.VISIBLE;
-import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
 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;
@@ -132,6 +131,7 @@
 import android.app.PendingIntent;
 import android.app.PictureInPictureParams;
 import android.app.ResultInfo;
+import android.app.servertransaction.ActivityConfigurationChangeItem;
 import android.app.servertransaction.ActivityLifecycleItem;
 import android.app.servertransaction.ActivityRelaunchItem;
 import android.app.servertransaction.ClientTransaction;
@@ -143,7 +143,6 @@
 import android.app.servertransaction.PipModeChangeItem;
 import android.app.servertransaction.ResumeActivityItem;
 import android.app.servertransaction.WindowVisibilityItem;
-import android.app.servertransaction.ActivityConfigurationChangeItem;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -163,7 +162,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.service.voice.IVoiceInteractionSession;
@@ -185,6 +183,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.AttributeCache;
 import com.android.server.AttributeCache.Entry;
+import com.android.server.am.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.uri.UriPermissionOwner;
 import com.android.server.wm.AppWindowContainerController;
@@ -265,9 +264,6 @@
     private int windowFlags;        // custom window flags for preview window.
     private TaskRecord task;        // the task this is in.
     private long createTime = System.currentTimeMillis();
-    long displayStartTime;  // when we started launching this activity
-    long fullyDrawnStartTime; // when we started launching this activity
-    private long startTime;         // last time this activity was started
     long lastVisibleTime;   // last time this activity became visible
     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
     long pauseTime;         // last time we started pausing the activity
@@ -287,7 +283,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
@@ -535,15 +531,6 @@
             pw.print("requestedVrComponent=");
             pw.println(requestedVrComponent);
         }
-        if (displayStartTime != 0 || startTime != 0) {
-            pw.print(prefix); pw.print("displayStartTime=");
-                    if (displayStartTime == 0) pw.print("0");
-                    else TimeUtils.formatDuration(displayStartTime, now, pw);
-                    pw.print(" startTime=");
-                    if (startTime == 0) pw.print("0");
-                    else TimeUtils.formatDuration(startTime, now, pw);
-                    pw.println();
-        }
         final boolean waitingVisible =
                 mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
         if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
@@ -562,8 +549,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));
@@ -1279,20 +1266,14 @@
 
     /**
      * Check whether this activity can be launched on the specified display.
+     *
      * @param displayId Target display id.
-     * @return {@code true} if either it is the default display or this activity is resizeable and
-     *         can be put a secondary screen.
+     * @return {@code true} if either it is the default display or this activity can be put on a
+     *         secondary screen.
      */
     boolean canBeLaunchedOnDisplay(int displayId) {
-        final TaskRecord task = getTask();
-
-        // The resizeability of an Activity's parent task takes precendence over the ActivityInfo.
-        // This allows for a non resizable activity to be launched into a resizeable task.
-        final boolean resizeable =
-                task != null ? task.isResizeable() : supportsResizeableMultiWindow();
-
-        return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
-                resizeable, launchedFromPid, launchedFromUid, info);
+        return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
+                launchedFromUid, info);
     }
 
     /**
@@ -2011,79 +1992,13 @@
     }
 
     public void reportFullyDrawnLocked(boolean restoredFromBundle) {
-        final long curTime = SystemClock.uptimeMillis();
-        if (displayStartTime != 0) {
-            reportLaunchTimeLocked(curTime);
+        final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
+                .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
+        if (info != null) {
+            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
+                    info.windowsFullyDrawnDelayMs);
         }
-        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
-                getWindowingMode());
-        if (fullyDrawnStartTime != 0 && entry != null) {
-            final long thisTime = curTime - fullyDrawnStartTime;
-            final long totalTime = entry.mFullyDrawnStartTime != 0
-                    ? (curTime - entry.mFullyDrawnStartTime) : thisTime;
-            if (SHOW_ACTIVITY_START_TIME) {
-                Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-                EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
-                        userId, System.identityHashCode(this), shortComponentName,
-                        thisTime, totalTime);
-                StringBuilder sb = service.mStringBuilder;
-                sb.setLength(0);
-                sb.append("Fully drawn ");
-                sb.append(shortComponentName);
-                sb.append(": ");
-                TimeUtils.formatDuration(thisTime, sb);
-                if (thisTime != totalTime) {
-                    sb.append(" (total ");
-                    TimeUtils.formatDuration(totalTime, sb);
-                    sb.append(")");
-                }
-                Log.i(TAG, sb.toString());
-            }
-            if (totalTime > 0) {
-                //service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
-            }
-            entry.mFullyDrawnStartTime = 0;
-        }
-        mStackSupervisor.getActivityMetricsLogger().logAppTransitionReportedDrawn(this,
-                restoredFromBundle);
-        fullyDrawnStartTime = 0;
     }
-
-    private void reportLaunchTimeLocked(final long curTime) {
-        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
-                getWindowingMode());
-        if (entry == null) {
-            return;
-        }
-        final long thisTime = curTime - displayStartTime;
-        final long totalTime = entry.mLaunchStartTime != 0
-                ? (curTime - entry.mLaunchStartTime) : thisTime;
-        if (SHOW_ACTIVITY_START_TIME) {
-            Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
-            EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
-                    userId, System.identityHashCode(this), shortComponentName,
-                    thisTime, totalTime);
-            StringBuilder sb = service.mStringBuilder;
-            sb.setLength(0);
-            sb.append("Displayed ");
-            sb.append(shortComponentName);
-            sb.append(": ");
-            TimeUtils.formatDuration(thisTime, sb);
-            if (thisTime != totalTime) {
-                sb.append(" (total ");
-                TimeUtils.formatDuration(totalTime, sb);
-                sb.append(")");
-            }
-            Log.i(TAG, sb.toString());
-        }
-        mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
-        if (totalTime > 0) {
-            //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
-        }
-        displayStartTime = 0;
-        entry.mLaunchStartTime = 0;
-    }
-
     @Override
     public void onStartingWindowDrawn(long timestamp) {
         synchronized (service.mGlobalLock) {
@@ -2095,13 +2010,12 @@
     @Override
     public void onWindowsDrawn(long timestamp) {
         synchronized (service.mGlobalLock) {
-            mStackSupervisor.getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(),
-                    timestamp);
-            if (displayStartTime != 0) {
-                reportLaunchTimeLocked(timestamp);
-            }
+            final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
+                    .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
+            final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
+            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
+                    windowsDrawnDelayMs);
             mStackSupervisor.sendWaitingVisibleReportLocked(this);
-            startTime = 0;
             finishLaunchTickingLocked();
             if (task != null) {
                 task.hasBeenVisible = true;
@@ -2331,7 +2245,7 @@
         }
 
         final CompatibilityInfo compatInfo =
-                service.mAm.compatibilityInfoForPackageLocked(info.applicationInfo);
+                service.compatibilityInfoForPackageLocked(info.applicationInfo);
         final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme,
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
@@ -2495,6 +2409,14 @@
         }
     }
 
+    /**
+     * @return {@code true} if this activity was reparented to another display but
+     *         {@link #ensureActivityConfiguration} is not called.
+     */
+    boolean shouldUpdateConfigForDisplayChanged() {
+        return mLastReportedDisplayId != getDisplayId();
+    }
+
     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
         return ensureActivityConfiguration(globalChanges, preserveWindow,
                 false /* ignoreStopState */);
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 aa4e68d..6388423 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -107,6 +107,7 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityController;
@@ -150,7 +151,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService.ItemMatcher;
 import com.android.server.wm.ConfigurationContainer;
@@ -162,7 +163,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;
@@ -1101,16 +1101,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 */);
         }
     }
 
@@ -1131,13 +1129,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;
         }
     }
 
@@ -1146,6 +1142,10 @@
         return mStackSupervisor.isFocusable(this, r != null && r.isFocusable());
     }
 
+    boolean isFocusableAndVisible() {
+        return isFocusable() && shouldBeVisible(null /* starting */);
+    }
+
     final boolean isAttached() {
         return getParent() != null;
     }
@@ -1317,16 +1317,13 @@
                 + " callers=" + Debug.getCallers(5));
         r.setState(RESUMED, "minimalResumeActivityLocked");
         r.completeResumeLocked();
-        mStackSupervisor.getLaunchTimeTracker().setLaunchTime(r);
         if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
                 "Launch completed; removing icicle of " + r.icicle);
     }
 
     private void clearLaunchTime(ActivityRecord r) {
         // Make sure that there is no activity waiting for this to launch.
-        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
-            r.displayStartTime = r.fullyDrawnStartTime = 0;
-        } else {
+        if (!mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
             mStackSupervisor.removeTimeoutsForActivityLocked(r);
             mStackSupervisor.scheduleIdleTimeoutLocked(r);
         }
@@ -1512,16 +1509,16 @@
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
 
-        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
+        mStackSupervisor.getActivityMetricsLogger().stopFullyDrawnTraceIfNeeded();
 
-        mService.mAm.updateCpuStats();
+        mService.updateCpuStats();
 
         if (prev.attachedToProcess()) {
             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
             try {
                 EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
                         prev.shortComponentName, "userLeaving=" + userLeaving);
-                mService.mAm.updateUsageStats(prev, false);
+                mService.updateUsageStats(prev, false);
 
                 mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                         prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
@@ -1683,19 +1680,15 @@
         if (prev != null) {
             prev.resumeKeyDispatchingLocked();
 
-            if (prev.hasProcess() && prev.cpuTimeAtResume > 0
-                    && mService.mAm.mBatteryStatsService.isOnBattery()) {
-                long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
+            if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
+                final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
                 if (diff > 0) {
-                    BatteryStatsImpl bsi = mService.mAm.mBatteryStatsService.getActiveStatistics();
-                    synchronized (bsi) {
-                        BatteryStatsImpl.Uid.Proc ps =
-                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
-                                        prev.info.packageName);
-                        if (ps != null) {
-                            ps.addForegroundTimeLocked(diff);
-                        }
-                    }
+                    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
@@ -1713,7 +1706,7 @@
         mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
     }
 
-    void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
+    private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
         if (!mStackSupervisor.mStoppingActivities.contains(r)) {
             mStackSupervisor.mStoppingActivities.add(r);
 
@@ -2407,7 +2400,7 @@
 
     @GuardedBy("mService")
     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
-        if (!mService.mAm.mBooting && !mService.mAm.mBooted) {
+        if (!mService.isBooting() && !mService.isBooted()) {
             // Not ready yet!
             return false;
         }
@@ -2437,10 +2430,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);
@@ -2455,13 +2449,24 @@
         if (shouldSleepOrShutDownActivities()
                 && mLastPausedActivity == next
                 && mStackSupervisor.allPausedActivitiesComplete()) {
-            // Make sure we have executed any pending transitions, since there
-            // should be nothing left to do at this point.
-            executeAppTransition(options);
-            if (DEBUG_STATES) Slog.d(TAG_STATES,
-                    "resumeTopActivityLocked: Going to sleep and all paused");
-            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
-            return false;
+            // If the current top activity may be able to occlude keyguard but the occluded state
+            // has not been set, update visibility and check again if we should continue to resume.
+            boolean nothingToResume = true;
+            if (!mService.mShuttingDown && !mTopActivityOccludesKeyguard
+                    && next.canShowWhenLocked()) {
+                ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
+                        !PRESERVE_WINDOWS);
+                nothingToResume = shouldSleepActivities();
+            }
+            if (nothingToResume) {
+                // Make sure we have executed any pending transitions, since there
+                // should be nothing left to do at this point.
+                executeAppTransition(options);
+                if (DEBUG_STATES) Slog.d(TAG_STATES,
+                        "resumeTopActivityLocked: Going to sleep and all paused");
+                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
+                return false;
+            }
         }
 
         // Make sure that the user who owns this activity is started.  If not,
@@ -2495,7 +2500,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.
@@ -2540,7 +2545,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:
@@ -2656,7 +2661,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);
@@ -2668,10 +2672,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
@@ -2688,10 +2692,10 @@
                 next.startLaunchTickingLocked();
 
                 ActivityRecord lastResumedActivity =
-                        lastStack == null ? null :lastStack.mResumedActivity;
+                        lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity;
                 final ActivityState lastState = next.getState();
 
-                mService.mAm.updateCpuStats();
+                mService.updateCpuStats();
 
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
                         + " (in existing)");
@@ -2793,8 +2797,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 */);
                     }
@@ -2852,9 +2856,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. */
@@ -3448,8 +3450,8 @@
         final String myReason = reason + " adjustFocus";
 
         if (next == r) {
-            mStackSupervisor.moveFocusableActivityStackToFrontLocked(
-                    mStackSupervisor.topRunningActivityLocked(), myReason);
+            mStackSupervisor.moveFocusableActivityToTop(mStackSupervisor.topRunningActivityLocked(),
+                    myReason);
             return;
         }
 
@@ -3480,7 +3482,7 @@
         }
 
         // Whatever...go home.
-        mStackSupervisor.moveHomeStackTaskToTop(myReason);
+        getDisplay().moveHomeActivityToTop(myReason);
     }
 
     /**
@@ -3509,7 +3511,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;
         }
 
@@ -4149,7 +4151,7 @@
             for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
                 PendingIntentRecord rec = apr.get();
                 if (rec != null) {
-                    mService.mAm.cancelIntentSenderLocked(rec, false);
+                    mService.mPendingIntentController.cancelIntentSender(rec, false);
                 }
             }
             r.pendingResults = null;
@@ -4166,7 +4168,7 @@
         mWindowManager.notifyAppRelaunchesCleared(r.appToken);
     }
 
-    void removeTimeoutsForActivityLocked(ActivityRecord r) {
+    private void removeTimeoutsForActivityLocked(ActivityRecord r) {
         mStackSupervisor.removeTimeoutsForActivityLocked(r);
         mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
         mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
@@ -4231,15 +4233,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) {
@@ -4368,12 +4366,8 @@
         if (hadApp) {
             if (removeFromApp) {
                 r.app.removeActivity(r);
-                if (mService.mAm.mHeavyWeightProcess != null
-                        && mService.mAm.mHeavyWeightProcess.getWindowProcessController() == r.app
-                        && !r.app.hasActivities()) {
-                    mService.mAm.mHeavyWeightProcess = null;
-                    mService.mAm.mHandler.sendEmptyMessage(
-                            ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
+                if (!r.app.hasActivities()) {
+                    mService.clearHeavyWeightProcessIfEquals(r.app);
                 }
                 if (!r.app.hasActivities()) {
                     // Update any services we are bound to that might care about whether
@@ -4564,7 +4558,7 @@
                                     r.getTask().taskId, r.shortComponentName,
                                     "proc died without state saved");
                             if (r.getState() == RESUMED) {
-                                mService.mAm.updateUsageStats(r, false);
+                                mService.updateUsageStats(r, false);
                             }
                         }
                     } else {
@@ -4621,22 +4615,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);
@@ -4684,7 +4662,7 @@
 
             // Set focus to the top running activity of this stack.
             final ActivityRecord r = topRunningActivityLocked();
-            mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
+            mStackSupervisor.moveFocusableActivityToTop(r, reason);
 
             if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
             if (noAnimation) {
@@ -5225,11 +5203,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()) {
@@ -5375,12 +5353,14 @@
         display.positionChildAtTop(this, false /* includingParents */);
     }
 
+    /** NOTE: Should only be called from {@link TaskRecord#reparent}. */
     void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
             boolean setPause, String reason) {
         if (!moveToFront) {
             return;
         }
 
+        final ActivityState origState = r.getState();
         // If the activity owns the last resumed activity, transfer that together,
         // so that we don't resume the same activity again in the new stack.
         // Apps may depend on onResume()/onPause() being called in pairs.
@@ -5393,9 +5373,14 @@
             mPausingActivity = r;
             schedulePauseTimeout(r);
         }
-        // Move the stack in which we are placing the activity to the front. The call will also
-        // make sure the activity focus is set.
+        // Move the stack in which we are placing the activity to the front.
         moveToFront(reason);
+        // If the original state is resumed, there is no state change to update focused app.
+        // So here makes sure the activity focus is set if it is the top.
+        if (origState == RESUMED && r == mStackSupervisor.getTopResumedActivity()) {
+            // TODO(b/111361570): Support multiple focused apps in WM
+            mService.setResumedActivityUncheckLocked(r, reason);
+        }
     }
 
     public int getStackId() {
@@ -5429,7 +5414,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 310898e..0477d73 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -25,6 +25,7 @@
 import static android.app.ActivityTaskManager.INVALID_STACK_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;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -39,6 +40,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;
@@ -49,7 +53,6 @@
 import static android.view.Display.INVALID_DISPLAY;
 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;
@@ -96,7 +99,6 @@
 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
-
 import static java.lang.Integer.MAX_VALUE;
 
 import android.Manifest;
@@ -131,6 +133,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;
@@ -155,6 +158,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;
@@ -334,15 +338,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
@@ -444,13 +439,12 @@
 
     // 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;
 
     private ActivityMetricsLogger mActivityMetricsLogger;
-    private LaunchTimeTracker mLaunchTimeTracker = new LaunchTimeTracker();
 
     private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
 
@@ -488,8 +482,8 @@
     }
 
     /** Check if placing task or activity on specified display is allowed. */
-    boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid,
-            int callingUid, ActivityInfo activityInfo) {
+    boolean canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid,
+            ActivityInfo activityInfo) {
         if (displayId == DEFAULT_DISPLAY) {
             // No restrictions for the default display.
             return true;
@@ -498,10 +492,6 @@
             // Can't launch on secondary displays if feature is not supported.
             return false;
         }
-        if (!resizeable && !displayConfigMatchesGlobal(displayId)) {
-            // Can't apply wrong configuration to non-resizeable activities.
-            return false;
-        }
         if (!isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, displayId, activityInfo)) {
             // Can't place activities to a display that has restricted launch rules.
             // In this case the request should be made by explicitly adding target display id and
@@ -650,10 +640,6 @@
         return mActivityMetricsLogger;
     }
 
-    LaunchTimeTracker getLaunchTimeTracker() {
-        return mLaunchTimeTracker;
-    }
-
     public KeyguardController getKeyguardController() {
         return mKeyguardController;
     }
@@ -690,19 +676,19 @@
         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
 
         final Display[] displays = mDisplayManager.getDisplays();
-        for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
+        for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
             final Display display = displays[displayNdx];
             final ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
             if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) {
                 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);
     }
 
@@ -742,10 +728,6 @@
     }
 
     ActivityRecord getTopResumedActivity() {
-        if (mWindowManager == null) {
-            return null;
-        }
-
         final ActivityStack focusedStack = getTopDisplayFocusedStack();
         if (focusedStack == null) {
             return null;
@@ -774,47 +756,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.mAm.mBooting || !mService.mAm.mBooted) {
-            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);
@@ -823,34 +768,47 @@
         }
     }
 
-    /** 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) {
-        if (!mService.mAm.mBooting && !mService.mAm.mBooted) {
+    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);
+            moveFocusableActivityToTop(r, 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) {
+            // No restrictions to default 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) {
@@ -1095,28 +1053,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) {
@@ -1183,8 +1119,8 @@
         }
     }
 
-    void waitActivityVisible(ComponentName name, WaitResult result) {
-        final WaitInfo waitInfo = new WaitInfo(name, result);
+    void waitActivityVisible(ComponentName name, WaitResult result, long startTimeMs) {
+        final WaitInfo waitInfo = new WaitInfo(name, result, startTimeMs);
         mWaitingForActivityVisible.add(waitInfo);
     }
 
@@ -1215,8 +1151,7 @@
                 changed = true;
                 result.timeout = false;
                 result.who = w.getComponent();
-                result.totalTime = SystemClock.uptimeMillis() - result.thisTime;
-                result.thisTime = result.totalTime;
+                result.totalTime = SystemClock.uptimeMillis() - w.getStartTime();
                 mWaitingForActivityVisible.remove(w);
             }
         }
@@ -1255,8 +1190,7 @@
         }
     }
 
-    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
-            long thisTime, long totalTime) {
+    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, long totalTime) {
         boolean changed = false;
         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
             WaitResult w = mWaitingActivityLaunched.remove(i);
@@ -1266,7 +1200,6 @@
                 if (r != null) {
                     w.who = new ComponentName(r.info.packageName, r.info.name);
                 }
-                w.thisTime = thisTime;
                 w.totalTime = totalTime;
                 // Do not modify w.result.
             }
@@ -1529,12 +1462,12 @@
                     // 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.mAm.compatibilityInfoForPackageLocked(r.info.applicationInfo);
+                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) {
@@ -1562,7 +1495,8 @@
                 // we have to always create a new Configuration here.
 
                 final MergedConfiguration mergedConfiguration = new MergedConfiguration(
-                        mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
+                        app.getWindowProcessController().getConfiguration(),
+                        r.getMergedOverrideConfiguration());
                 r.setLastReportedConfiguration(mergedConfiguration);
 
                 logIfTransactionTooLarge(r.intent, r.icicle);
@@ -1594,23 +1528,18 @@
                 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
 
                 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
-                        && mService.mAm.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.
+                        && 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 (mService.mAm.mHeavyWeightProcess != null
-                                && mService.mAm.mHeavyWeightProcess != app) {
-                            Slog.w(TAG, "Starting new heavy weight process " + app
+                        if (mService.mHeavyWeightProcess != null
+                                && mService.mHeavyWeightProcess != proc) {
+                            Slog.w(TAG, "Starting new heavy weight process " + proc
                                     + " when already running "
-                                    + mService.mAm.mHeavyWeightProcess);
+                                    + mService.mHeavyWeightProcess);
                         }
-                        mService.mAm.mHeavyWeightProcess = app;
-                        Message msg = mService.mAm.mHandler.obtainMessage(
-                                ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
-                        msg.obj = r;
-                        mService.mAm.mHandler.sendMessage(msg);
+                        mService.setHeavyWeightProcess(r);
                     }
                 }
 
@@ -1736,8 +1665,6 @@
         ProcessRecord app = mService.mAm.getProcessRecordLocked(r.processName,
                 r.info.applicationInfo.uid, true);
 
-        getLaunchTimeTracker().setLaunchTime(r);
-
         if (app != null && app.thread != null) {
             try {
                 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
@@ -1970,7 +1897,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;
@@ -2057,15 +1984,15 @@
      */
     @GuardedBy("mService")
     private boolean checkFinishBootingLocked() {
-        final boolean booting = mService.mAm.mBooting;
+        final boolean booting = mService.isBooting();
         boolean enableScreen = false;
-        mService.mAm.mBooting = false;
-        if (!mService.mAm.mBooted) {
-            mService.mAm.mBooted = true;
+        mService.setBooting(false);
+        if (!mService.isBooted()) {
+            mService.setBooted(true);
             enableScreen = true;
         }
         if (booting || enableScreen) {
-            mService.mAm.postFinishBooting(booting, enableScreen);
+            mService.postFinishBooting(booting, enableScreen);
         }
         return booting;
     }
@@ -2090,7 +2017,7 @@
             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
             r.finishLaunchTickingLocked();
             if (fromTimeout) {
-                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
+                reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY);
             }
 
             // This is a hack to semi-deal with a race condition
@@ -2223,7 +2150,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);
         }
     }
 
@@ -2292,7 +2220,8 @@
             return false;
         }
 
-        if (targetStack != null && targetStack.isTopStackOnDisplay()) {
+        if (targetStack != null && (targetStack.isTopStackOnDisplay()
+                || getTopDisplayFocusedStack() == targetStack)) {
             return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
         }
 
@@ -2365,7 +2294,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");
@@ -2376,13 +2305,15 @@
             mUserLeaving = true;
         }
 
+        // TODO(b/111363427): The moving-to-top task may not be on the top display, so it could be
+        // different from where the prev activity stays on.
         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");
+            currentStack.getDisplay().moveHomeStackToFront("findTaskToMoveToFront");
         }
 
         if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
@@ -2394,7 +2325,7 @@
             if (stack != currentStack) {
                 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME,
                         "findTaskToMoveToFront");
-                stack = currentStack;
+                currentStack = stack;
                 // moveTaskToStackUncheckedLocked() should already placed the task on top,
                 // still need moveTaskToFrontLocked() below for any transition settings.
             }
@@ -2661,6 +2592,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) {
@@ -2704,25 +2641,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;
     }
 
@@ -3196,10 +3120,10 @@
 
         // Kill the running processes. Post on handle since we don't want to hold the service lock
         // while calling into AM.
-        final Runnable r = PooledLambda.obtainRunnable(
+        final Message m = PooledLambda.obtainMessage(
                 ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal,
                 procsToKill);
-        mService.mH.post(r);
+        mService.mH.sendMessage(m);
     }
 
     /**
@@ -3436,7 +3360,8 @@
     }
 
     /** Move activity with its stack to front and make the stack focused. */
-    boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
+    // TODO(b/111363427): Move this method to ActivityRecord.
+    boolean moveFocusableActivityToTop(ActivityRecord r, String reason) {
         if (r == null || !r.isFocusable()) {
             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
                     "moveActivityStackToFront: unfocusable r=" + r);
@@ -3605,7 +3530,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
@@ -3686,9 +3611,9 @@
 
         final ActivityStack stack = r.getStack();
         if (isTopDisplayFocusedStack(stack)) {
-            mService.mAm.updateUsageStats(r, true);
+            mService.updateUsageStats(r, true);
         }
-        if (allResumedActivitiesComplete()) {
+        if (stack.getDisplay().allResumedActivitiesComplete()) {
             ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
             mWindowManager.executeAppTransition();
             return true;
@@ -3845,7 +3770,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);
@@ -3863,14 +3789,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;
     }
@@ -3993,8 +3919,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);
@@ -4290,6 +4218,7 @@
     private void handleDisplayAdded(int displayId) {
         synchronized (mService.mGlobalLock) {
             getActivityDisplayOrCreateLocked(displayId);
+            mService.startHomeActivityLocked(mCurrentUser, "displayAdded", displayId);
         }
     }
 
@@ -4336,7 +4265,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;
     }
@@ -4354,10 +4282,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) {
@@ -4530,11 +4461,14 @@
             mService.setTaskWindowingMode(task.taskId,
                     WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
             if (preferredDisplayId != actualDisplayId) {
-                // Display a warning toast that we tried to put a non-resizeable task on a secondary
-                // display with config different from global config.
+                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.
                 mService.getTaskChangeNotificationController()
                         .notifyActivityLaunchOnSecondaryDisplayFailed();
                 return;
+            } else if (!forceNonResizable && handleForcedResizableTask(task,
+                    FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY)) {
+                return;
             }
         }
 
@@ -4554,16 +4488,23 @@
             return;
         }
 
+        handleForcedResizableTask(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
+    }
+
+    /**
+     * @return {@code true} if the top activity of the task is forced to be resizable and the user
+     *         was notified about activity being forced resized.
+     */
+    private boolean handleForcedResizableTask(TaskRecord task, int reason) {
         final ActivityRecord topActivity = task.getTopActivity();
         if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
-            && !topActivity.noDisplay) {
+                && !topActivity.noDisplay) {
             final String packageName = topActivity.appInfo.packageName;
-            final int reason = isSecondaryDisplayPreferred
-                    ? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY
-                    : FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
             mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
                     task.taskId, reason, packageName);
+            return true;
         }
+        return false;
     }
 
     void activityRelaunchedLocked(IBinder token) {
@@ -4843,7 +4784,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
@@ -4886,12 +4828,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)
@@ -4938,10 +4881,13 @@
     static class WaitInfo {
         private final ComponentName mTargetComponent;
         private final WaitResult mResult;
+        /** Time stamp when we started to wait for {@link WaitResult}. */
+        private final long mStartTimeMs;
 
-        public WaitInfo(ComponentName targetComponent, WaitResult result) {
+        WaitInfo(ComponentName targetComponent, WaitResult result, long startTimeMs) {
             this.mTargetComponent = targetComponent;
             this.mResult = result;
+            this.mStartTimeMs = startTimeMs;
         }
 
         public boolean matches(ComponentName targetComponent) {
@@ -4952,6 +4898,10 @@
             return mResult;
         }
 
+        public long getStartTime() {
+            return mStartTimeMs;
+        }
+
         public ComponentName getComponent() {
             return mTargetComponent;
         }
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 6e3a79c..f6f1e55 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 android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
 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 android.app.ActivityOptions;
 import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -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. */
@@ -161,13 +164,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) {
@@ -191,9 +201,8 @@
         // 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) {
+        if (mService.mFactoryTest != FACTORY_TEST_LOW_LEVEL
+                && Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
             mService.mAm.setCheckedForSetup(true);
 
             // See if we should be showing the platform update setup UI.
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 177e2f5..4789ff3 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -126,7 +126,7 @@
 
     private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) {
         Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary();
-        final IIntentSender target = mService.mAm.getIntentSenderLocked(
+        final IIntentSender target = mService.getIntentSenderLocked(
                 INTENT_SENDER_ACTIVITY, mCallingPackage, callingUid, mUserId, null /*token*/,
                 null /*resultCode*/, 0 /*requestCode*/,
                 new Intent[] { mIntent }, new String[] { mResolvedType },
@@ -277,7 +277,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 bcb2b9b..2bd22e8 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -783,7 +783,7 @@
         if (aInfo != null) {
             if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                     aInfo.packageName, userId)) {
-                IIntentSender target = mService.mAm.getIntentSenderLocked(
+                IIntentSender target = mService.getIntentSenderLocked(
                         ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                         callingUid, userId, null, null, 0, new Intent[]{intent},
                         new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
@@ -945,7 +945,8 @@
                 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
     }
 
-    void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
+    void postStartActivityProcessing(ActivityRecord r, int result,
+            ActivityStack startedActivityStack) {
         if (ActivityManager.isStartResultFatalError(result)) {
             return;
         }
@@ -957,14 +958,6 @@
         // about this, so it waits for the new activity to become visible instead.
         mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
 
-        ActivityStack startedActivityStack = null;
-        final ActivityStack currentStack = r.getStack();
-        if (currentStack != null) {
-            startedActivityStack = currentStack;
-        } else if (mTargetStack != null) {
-            startedActivityStack = targetStack;
-        }
-
         if (startedActivityStack == null) {
             return;
         }
@@ -982,7 +975,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();
                     }
@@ -1082,13 +1076,13 @@
             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)) {
-                    final ProcessRecord heavy = mService.mAm.mHeavyWeightProcess;
-                    if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
-                            || !heavy.processName.equals(aInfo.processName))) {
+                    final WindowProcessController heavy = mService.mHeavyWeightProcess;
+                    if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
+                            || !heavy.mName.equals(aInfo.processName))) {
                         int appCallingUid = callingUid;
                         if (caller != null) {
                             ProcessRecord callerApp = mService.mAm.getRecordForAppLocked(caller);
@@ -1103,7 +1097,7 @@
                             }
                         }
 
-                        IIntentSender target = mService.mAm.getIntentSenderLocked(
+                        IIntentSender target = mService.getIntentSenderLocked(
                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
                                 appCallingUid, userId, null, null, 0, new Intent[] { intent },
                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
@@ -1116,8 +1110,7 @@
                         }
                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
                                 new IntentSender(target));
-                        heavy.getWindowProcessController().updateIntentForHeavyWeightActivity(
-                                newIntent);
+                        heavy.updateIntentForHeavyWeightActivity(newIntent);
                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
                                 aInfo.packageName);
                         newIntent.setFlags(intent.getFlags());
@@ -1162,6 +1155,9 @@
                 mService.updateConfigurationLocked(globalConfig, null, false);
             }
 
+            // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
+            // will then wait for the windows to be drawn and populate WaitResult.
+            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
             if (outResult != null) {
                 outResult.result = res;
 
@@ -1186,7 +1182,6 @@
                         outResult.timeout = false;
                         outResult.who = r.realActivity;
                         outResult.totalTime = 0;
-                        outResult.thisTime = 0;
                         break;
                     }
                     case START_TASK_TO_FRONT: {
@@ -1196,10 +1191,9 @@
                             outResult.timeout = false;
                             outResult.who = r.realActivity;
                             outResult.totalTime = 0;
-                            outResult.thisTime = 0;
                         } else {
-                            outResult.thisTime = SystemClock.uptimeMillis();
-                            mSupervisor.waitActivityVisible(r.realActivity, outResult);
+                            final long startTimeMs = SystemClock.uptimeMillis();
+                            mSupervisor.waitActivityVisible(r.realActivity, outResult, startTimeMs);
                             // Note: the timeout variable is not currently not ever set.
                             do {
                                 try {
@@ -1213,7 +1207,6 @@
                 }
             }
 
-            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
             return res;
         }
     }
@@ -1240,23 +1233,41 @@
                 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                 ActivityRecord[] outActivity) {
         int result = START_CANCELED;
+        final ActivityStack startedActivityStack;
         try {
             mService.mWindowManager.deferSurfaceLayout();
             result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                     startFlags, doResume, options, inTask, outActivity);
         } finally {
-            // If we are not able to proceed, disassociate the activity from the task. Leaving an
-            // activity in an incomplete state can lead to issues, such as performing operations
-            // without a window container.
-            final ActivityStack stack = mStartActivity.getStack();
-            if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
-                stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
-                        null /* intentResultData */, "startActivity", true /* oomAdj */);
+            final ActivityStack currentStack = r.getStack();
+            startedActivityStack = currentStack != null ? currentStack : mTargetStack;
+
+            if (ActivityManager.isStartResultSuccessful(result)) {
+                if (startedActivityStack != null) {
+                    // If there is no state change (e.g. a resumed activity is reparented to
+                    // top of another display) to trigger a visibility/configuration checking,
+                    // we have to update the configuration for changing to different display.
+                    final ActivityRecord currentTop =
+                            startedActivityStack.topRunningActivityLocked();
+                    if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
+                        mSupervisor.ensureVisibilityAndConfig(currentTop, currentTop.getDisplayId(),
+                                true /* markFrozenIfConfigChanged */, false /* deferResume */);
+                    }
+                }
+            } else {
+                // If we are not able to proceed, disassociate the activity from the task.
+                // Leaving an activity in an incomplete state can lead to issues, such as
+                // performing operations without a window container.
+                final ActivityStack stack = mStartActivity.getStack();
+                if (stack != null) {
+                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
+                            null /* intentResultData */, "startActivity", true /* oomAdj */);
+                }
             }
             mService.mWindowManager.continueSurfaceLayout();
         }
 
-        postStartActivityProcessing(r, result, mTargetStack);
+        postStartActivityProcessing(r, result, startedActivityStack);
 
         return result;
     }
@@ -1270,6 +1281,15 @@
         setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                 voiceInteractor);
 
+        // 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();
 
         computeSourceStack();
@@ -1420,7 +1440,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;
@@ -1848,6 +1872,13 @@
                 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;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 212844a..8e3eeae 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -39,6 +39,7 @@
 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_NEW_TASK;
+import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
 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 +47,9 @@
 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.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
@@ -86,7 +90,6 @@
 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.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
@@ -125,7 +128,11 @@
 import android.app.IActivityTaskManager;
 import android.app.IApplicationThread;
 import android.app.IAssistDataReceiver;
+import android.app.INotificationManager;
 import android.app.ITaskStackListener;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.app.PictureInPictureParams;
 import android.app.ProfilerInfo;
 import android.app.RemoteAction;
@@ -145,11 +152,13 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
+import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -161,6 +170,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;
@@ -208,10 +218,13 @@
 import com.android.internal.app.ProcessMap;
 import com.android.internal.logging.MetricsLogger;
 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.logging.MetricsLoggerWrapper;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.KeyguardDismissCallback;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AppOpsService;
 import com.android.server.AttributeCache;
 import com.android.server.LocalServices;
@@ -230,7 +243,9 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 
@@ -266,6 +281,8 @@
     ActivityManagerInternal mAmInternal;
     UriGrantsManagerInternal mUgmInternal;
     private PackageManagerInternal mPmInternal;
+    private ActivityTaskManagerInternal mInternal;
+    PendingIntentController mPendingIntentController;
     /* Global service lock used by the package the owns this service. */
     Object mGlobalLock;
     ActivityStackSupervisor mStackSupervisor;
@@ -278,6 +295,9 @@
     final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
     /** This is the process holding what we currently consider to be the "home" activity. */
     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.
@@ -373,6 +393,13 @@
     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;
+
     /**
      * Used to retain an update lock when the foreground activity is in
      * immersive mode.
@@ -475,6 +502,12 @@
 
     private AppWarnings mAppWarnings;
 
+    /**
+     * Packages that the user has asked to have run in screen size
+     * compatibility mode instead of filling the screen.
+     */
+    CompatModePackages mCompatModePackages;
+
     private FontScaleSettingObserver mFontScaleSettingObserver;
 
     private final class FontScaleSettingObserver extends ContentObserver {
@@ -503,11 +536,14 @@
 
     ActivityTaskManagerService(Context context) {
         mContext = context;
+        mFactoryTest = FactoryTest.getMode();
         mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
         mLifecycleManager = new ClientLifecycleManager();
     }
 
     void onSystemReady() {
+        mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_CANT_SAVE_STATE);
         mAssistUtils = new AssistUtils(mContext);
         mVrController.onSystemReady();
         mRecentTasks.onSystemReadyLocked();
@@ -607,8 +643,10 @@
         mGlobalLock = mAm;
         mH = new H(mAm.mHandlerThread.getLooper());
         mUiHandler = new UiHandler();
-        mAppWarnings = new AppWarnings(
-                this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
+        final File systemDir = SystemServiceManager.ensureSystemDir();
+        mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
+        mCompatModePackages = new CompatModePackages(this, systemDir, mH);
+        mPendingIntentController = mAm.mPendingIntentController;
 
         mTempConfig.setToDefaults();
         mTempConfig.setLocales(LocaleList.getDefault());
@@ -631,6 +669,11 @@
         mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
     }
 
+    int increaseConfigurationSeqLocked() {
+        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
+        return mConfigurationSeq;
+    }
+
     protected ActivityStackSupervisor createStackSupervisor() {
         final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
         supervisor.initialize();
@@ -686,8 +729,49 @@
         return mLockTaskController;
     }
 
+    /**
+     * Return the global configuration used by the process corresponding to the input pid. This is
+     * usually the global configuration with some overrides specific to that process.
+     */
+    Configuration getGlobalConfigurationForCallingPid() {
+        final int pid = Binder.getCallingPid();
+        if (pid == MY_PID || pid < 0) {
+            return getGlobalConfiguration();
+        }
+        synchronized (mGlobalLock) {
+            final WindowProcessController app = mPidMap.get(pid);
+            return app != null ? app.getConfiguration() : getGlobalConfiguration();
+        }
+    }
+
+    /**
+     * Return the device configuration info used by the process corresponding to the input pid.
+     * The value is consistent with the global configuration for the process.
+     */
+    @Override
+    public ConfigurationInfo getDeviceConfigurationInfo() {
+        ConfigurationInfo config = new ConfigurationInfo();
+        synchronized (mGlobalLock) {
+            final Configuration globalConfig = getGlobalConfigurationForCallingPid();
+            config.reqTouchScreen = globalConfig.touchscreen;
+            config.reqKeyboardType = globalConfig.keyboard;
+            config.reqNavigation = globalConfig.navigation;
+            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
+                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
+                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
+            }
+            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
+                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
+                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
+            }
+            config.reqGlEsVersion = mAm.GL_ES_VERSION;
+        }
+        return config;
+    }
+
     private void start() {
-        LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
+        mInternal = new LocalService();
+        LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
     }
 
     public static final class Lifecycle extends SystemService {
@@ -1461,16 +1545,13 @@
     @Override
     public int getFrontActivityScreenCompatMode() {
         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
-        ApplicationInfo ai;
         synchronized (mGlobalLock) {
             final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
             if (r == null) {
                 return ActivityManager.COMPAT_MODE_UNKNOWN;
             }
-            ai = r.info.applicationInfo;
+            return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
         }
-
-        return mAmInternal.getPackageScreenCompatMode(ai);
     }
 
     @Override
@@ -1485,9 +1566,8 @@
                 return;
             }
             ai = r.info.applicationInfo;
+            mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
         }
-
-        mAmInternal.setPackageScreenCompatMode(ai, mode);
     }
 
     @Override
@@ -1627,8 +1707,7 @@
                     return;
                 }
                 final ActivityRecord r = stack.topRunningActivityLocked();
-                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
-                        r, "setFocusedStack")) {
+                if (mStackSupervisor.moveFocusableActivityToTop(r, "setFocusedStack")) {
                     mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
                 }
             }
@@ -1649,7 +1728,7 @@
                     return;
                 }
                 final ActivityRecord r = task.topRunningActivityLocked();
-                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
+                if (mStackSupervisor.moveFocusableActivityToTop(r, "setFocusedTask")) {
                     mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
                 }
             }
@@ -1895,10 +1974,12 @@
             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
             if (task == null) {
                 Slog.d(TAG, "Could not find task for id: "+ taskId);
+                SafeActivityOptions.abort(options);
                 return;
             }
             if (getLockTaskController().isLockTaskModeViolation(task)) {
                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+                SafeActivityOptions.abort(options);
                 return;
             }
             ActivityOptions realOptions = options != null
@@ -1918,7 +1999,6 @@
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
-        SafeActivityOptions.abort(options);
     }
 
     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
@@ -2905,7 +2985,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);
         }
@@ -2923,6 +3003,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
@@ -4112,7 +4198,7 @@
         return mVrController.shouldDisableNonVrUiLocked();
     }
 
-    void applyUpdateVrModeLocked(ActivityRecord r) {
+    private void applyUpdateVrModeLocked(ActivityRecord r) {
         // VR apps are expected to run in a main display. If an app is turning on VR for
         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
         // fullscreen stack before enabling VR Mode.
@@ -4143,6 +4229,40 @@
         });
     }
 
+    @Override
+    public int getPackageScreenCompatMode(String packageName) {
+        enforceNotIsolatedCaller("getPackageScreenCompatMode");
+        synchronized (mGlobalLock) {
+            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
+        }
+    }
+
+    @Override
+    public void setPackageScreenCompatMode(String packageName, int mode) {
+        mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+                "setPackageScreenCompatMode");
+        synchronized (mGlobalLock) {
+            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
+        }
+    }
+
+    @Override
+    public boolean getPackageAskScreenCompat(String packageName) {
+        enforceNotIsolatedCaller("getPackageAskScreenCompat");
+        synchronized (mGlobalLock) {
+            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
+        }
+    }
+
+    @Override
+    public void setPackageAskScreenCompat(String packageName, boolean ask) {
+        mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+                "setPackageAskScreenCompat");
+        synchronized (mGlobalLock) {
+            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
+        }
+    }
+
     ActivityStack getTopDisplayFocusedStack() {
         return mStackSupervisor.getTopDisplayFocusedStack();
     }
@@ -4215,7 +4335,7 @@
     public Configuration getConfiguration() {
         Configuration ci;
         synchronized(mGlobalLock) {
-            ci = new Configuration(getGlobalConfiguration());
+            ci = new Configuration(getGlobalConfigurationForCallingPid());
             ci.userSetLocale = false;
         }
         return ci;
@@ -4371,8 +4491,7 @@
                     locales.get(bestLocaleIndex)));
         }
 
-        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
-        mTempConfig.seq = mConfigurationSeq;
+        mTempConfig.seq = increaseConfigurationSeqLocked();
 
         // Update stored global config and notify everyone about the change.
         mStackSupervisor.onConfigurationChanged(mTempConfig);
@@ -4406,6 +4525,7 @@
             mAm.mHandler.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 {
@@ -4688,11 +4808,7 @@
         return mSleeping;
     }
 
-    /**
-     * Update AMS states when an activity is resumed. This should only be called by
-     * {@link ActivityStack#onActivityStateChanged(
-     * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
-     */
+    /** Update AMS states when an activity is resumed. */
     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
         final TaskRecord task = r.getTask();
         if (task.isActivityTypeStandard()) {
@@ -4750,8 +4866,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);
@@ -4812,6 +4927,155 @@
         mH.post(mAmInternal::updateOomAdj);
     }
 
+    void updateCpuStats() {
+        mH.post(mAmInternal::updateCpuStats);
+    }
+
+    void updateUsageStats(ActivityRecord component, boolean resumed) {
+        final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
+                mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
+        mH.sendMessage(m);
+    }
+
+    void setBooting(boolean booting) {
+        mAmInternal.setBooting(booting);
+    }
+
+    boolean isBooting() {
+        return mAmInternal.isBooting();
+    }
+
+    void setBooted(boolean booted) {
+        mAmInternal.setBooted(booted);
+    }
+
+    boolean isBooted() {
+        return mAmInternal.isBooted();
+    }
+
+    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
+        mH.post(() -> {
+            if (finishBooting) {
+                mAmInternal.finishBooting();
+            }
+            if (enableScreen) {
+                mInternal.enableScreenAfterBoot(isBooted());
+            }
+        });
+    }
+
+    void setHeavyWeightProcess(ActivityRecord root) {
+        mHeavyWeightProcess = root.app;
+        final Message m = PooledLambda.obtainMessage(
+                ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
+                root.app, root.intent, root.userId);
+        mH.sendMessage(m);
+    }
+
+    void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
+        if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
+            return;
+        }
+
+        mHeavyWeightProcess = null;
+        final Message m = PooledLambda.obtainMessage(
+                ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
+                proc.mUserId);
+        mH.sendMessage(m);
+    }
+
+    private void cancelHeavyWeightProcessNotification(int userId) {
+        final INotificationManager inm = NotificationManager.getService();
+        if (inm == null) {
+            return;
+        }
+        try {
+            inm.cancelNotificationWithTag("android", null,
+                    SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Error canceling notification for service", e);
+        } catch (RemoteException e) {
+        }
+
+    }
+
+    private void postHeavyWeightProcessNotification(
+            WindowProcessController proc, Intent intent, int userId) {
+        if (proc == null) {
+            return;
+        }
+
+        final INotificationManager inm = NotificationManager.getService();
+        if (inm == null) {
+            return;
+        }
+
+        try {
+            Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
+            String text = mContext.getString(R.string.heavy_weight_notification,
+                    context.getApplicationInfo().loadLabel(context.getPackageManager()));
+            Notification notification =
+                    new Notification.Builder(context,
+                            SystemNotificationChannels.HEAVY_WEIGHT_APP)
+                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                            .setWhen(0)
+                            .setOngoing(true)
+                            .setTicker(text)
+                            .setColor(mContext.getColor(
+                                    com.android.internal.R.color.system_notification_accent_color))
+                            .setContentTitle(text)
+                            .setContentText(
+                                    mContext.getText(R.string.heavy_weight_notification_detail))
+                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
+                                    intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
+                                    new UserHandle(userId)))
+                            .build();
+            try {
+                inm.enqueueNotificationWithTag("android", "android", null,
+                        SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error showing notification for heavy-weight app", e);
+            } catch (RemoteException e) {
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.w(TAG, "Unable to create context for heavy notification", e);
+        }
+
+    }
+
+    IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
+            IBinder token, String resultWho, int requestCode, Intent[] intents,
+            String[] resolvedTypes, int flags, Bundle bOptions) {
+
+        ActivityRecord activity = null;
+        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
+            activity = ActivityRecord.isInStackLocked(token);
+            if (activity == null) {
+                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
+                return null;
+            }
+            if (activity.finishing) {
+                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
+                return null;
+            }
+        }
+
+        final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
+                callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
+                bOptions);
+        final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
+        if (noCreate) {
+            return rec;
+        }
+        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
+            if (activity.pendingResults == null) {
+                activity.pendingResults = new HashSet<>();
+            }
+            activity.pendingResults.add(rec.ref);
+        }
+        return rec;
+    }
+
     // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
     private void startTimeTrackingFocusedActivityLocked() {
         final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
@@ -4888,6 +5152,10 @@
         mH.post(() -> mAmInternal.scheduleAppGcs());
     }
 
+    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
+        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
+    }
+
     /**
      * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
      * PackageManager could be unavailable at construction time and therefore needs to be accessed
@@ -4908,6 +5176,103 @@
         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;
+    }
+
+    private 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);
+    }
+
     void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
         if (true || Build.IS_USER) {
             return;
@@ -5014,7 +5379,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;
             }
         }
@@ -5099,6 +5465,31 @@
         }
 
         @Override
+        public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
+                String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
+                boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
+            synchronized (mGlobalLock) {
+                return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
+                        intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
+                        originatingPendingIntent);
+            }
+        }
+
+        @Override
+        public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
+                String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
+                String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
+                int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
+                PendingIntentRecord originatingPendingIntent) {
+            synchronized (mGlobalLock) {
+                return getActivityStartController().startActivityInPackage(uid, realCallingPid,
+                        realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
+                        requestCode, startFlags, options, userId, inTask, reason,
+                        validateIncomingUser, originatingPendingIntent);
+            }
+        }
+
+        @Override
         public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
                 Intent intent, Bundle options, int userId) {
             return ActivityTaskManagerService.this.startActivityAsUser(
@@ -5163,8 +5554,7 @@
                     throw new IllegalArgumentException(
                             "setFocusedActivity: No activity record matching token=" + token);
                 }
-                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
-                        r, "setFocusedActivity")) {
+                if (mStackSupervisor.moveFocusableActivityToTop(r, "setFocusedActivity")) {
                     mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
                 }
             }
@@ -5274,6 +5664,28 @@
         }
 
         @Override
+        public boolean isHeavyWeightProcess(WindowProcessController proc) {
+            synchronized (mGlobalLock) {
+                return proc == mHeavyWeightProcess;
+            }
+        }
+
+        @Override
+        public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
+            synchronized (mGlobalLock) {
+                ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
+            }
+        }
+
+        @Override
+        public void finishHeavyWeightApp() {
+            synchronized (mGlobalLock) {
+                ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
+                        mHeavyWeightProcess);
+            }
+        }
+
+        @Override
         public boolean isSleeping() {
             synchronized (mGlobalLock) {
                 return isSleepingLocked();
@@ -5382,6 +5794,7 @@
         @Override
         public void onPackageDataCleared(String name) {
             synchronized (mGlobalLock) {
+                mCompatModePackages.handlePackageDataClearedLocked(name);
                 mAppWarnings.onPackageDataCleared(name);
             }
         }
@@ -5390,6 +5803,183 @@
         public void onPackageUninstalled(String name) {
             synchronized (mGlobalLock) {
                 mAppWarnings.onPackageUninstalled(name);
+                mCompatModePackages.handlePackageUninstalledLocked(name);
+            }
+        }
+
+        @Override
+        public void onPackageAdded(String name, boolean replacing) {
+            synchronized (mGlobalLock) {
+                mCompatModePackages.handlePackageAddedLocked(name, replacing);
+            }
+        }
+
+        @Override
+        public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
+            synchronized (mGlobalLock) {
+                return compatibilityInfoForPackageLocked(ai);
+            }
+        }
+
+        /**
+         * Set the corresponding display information for the process global configuration. To be
+         * called when we need to show IME on a different display.
+         *
+         * @param pid The process id associated with the IME window.
+         * @param displayId The ID of the display showing the IME.
+         */
+        @Override
+        public void onImeWindowSetOnDisplay(int pid, int displayId) {
+            if (pid == MY_PID || pid < 0) {
+                if (DEBUG_CONFIGURATION) {
+                    Slog.w(TAG,
+                            "Trying to update display configuration for system/invalid process.");
+                }
+                return;
+            }
+            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.
+                        if (DEBUG_CONFIGURATION) {
+                            Slog.w(TAG, "Trying to update display configuration for non-existing "
+                                            + "displayId=" + displayId);
+                        }
+                        return;
+                    }
+                    final WindowProcessController imeProcess = mPidMap.get(pid);
+                    if (imeProcess == null) {
+                        if (DEBUG_CONFIGURATION) {
+                            Slog.w(TAG, "Trying to update display configuration for invalid pid: "
+                                            + pid);
+                        }
+                        return;
+                    }
+                    // Fetch the current override configuration of the display and set it to the
+                    // process global configuration.
+                    imeProcess.onConfigurationChanged(
+                            mStackSupervisor.getDisplayOverrideConfiguration(displayId));
+                }
+            });
+        }
+
+        @Override
+        public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
+                int requestCode, int resultCode, Intent data) {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+                if (r != null && r.getStack() != null) {
+                    r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
+                            resultCode, data);
+                }
+            }
+        }
+
+        @Override
+        public void clearPendingResultForActivity(IBinder activityToken,
+                WeakReference<PendingIntentRecord> pir) {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+                if (r != null && r.pendingResults != null) {
+                    r.pendingResults.remove(pir);
+                }
+            }
+        }
+
+        @Override
+        public IIntentSender getIntentSender(int type, String packageName,
+                int callingUid, int userId, IBinder token, String resultWho,
+                int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
+                Bundle bOptions) {
+            synchronized (mGlobalLock) {
+                return getIntentSenderLocked(type, packageName, callingUid, userId, token,
+                        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();
+                    mAm.ensureBootCompleted();
+                });
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 0a7e127..e2035f6 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -302,7 +302,7 @@
             mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                       PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
-                    mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
+                    mService.compatibilityInfoForPackage(r.curReceiver.applicationInfo),
                     r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
                     app.getReportedProcState());
             if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
@@ -741,7 +741,7 @@
 
         // Show a permission review UI only for explicit broadcast from a foreground app
         if (callerForeground && receiverRecord.intent.getComponent() != null) {
-            IIntentSender target = mService.getIntentSenderLocked(
+            IIntentSender target = mService.mPendingIntentController.getIntentSender(
                     ActivityManager.INTENT_SENDER_BROADCAST, receiverRecord.callerPackage,
                     receiverRecord.callingUid, receiverRecord.userId, null, null, 0,
                     new Intent[]{receiverRecord.intent},
@@ -1668,7 +1668,7 @@
 
     final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
                 || mPendingBroadcast != null) {
             boolean printed = false;
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 77efbfc..536f3a9 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -51,13 +51,13 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "CompatModePackages" : TAG_AM;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
-    private final ActivityManagerService mService;
+    private final ActivityTaskManagerService mService;
     private final AtomicFile mFile;
 
     // Compatibility state: no longer ask user to select the mode.
-    public static final int COMPAT_FLAG_DONT_ASK = 1<<0;
+    private static final int COMPAT_FLAG_DONT_ASK = 1<<0;
     // Compatibility state: compatibility mode is enabled.
-    public static final int COMPAT_FLAG_ENABLED = 1<<1;
+    private static final int COMPAT_FLAG_ENABLED = 1<<1;
 
     private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
 
@@ -80,7 +80,7 @@
         }
     };
 
-    public CompatModePackages(ActivityManagerService service, File systemDir, Handler handler) {
+    public CompatModePackages(ActivityTaskManagerService service, File systemDir, Handler handler) {
         mService = service;
         mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"), "compat-mode");
         mHandler = new CompatHandler(handler.getLooper());
@@ -317,12 +317,12 @@
 
             scheduleWrite();
 
-            final ActivityStack stack = mService.mActivityTaskManager.getTopDisplayFocusedStack();
+            final ActivityStack stack = mService.getTopDisplayFocusedStack();
             ActivityRecord starting = stack.restartPackage(packageName);
 
             // Tell all processes that loaded this package about the change.
-            for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
-                ProcessRecord app = mService.mLruProcesses.get(i);
+            for (int i = mService.mAm.mLruProcesses.size() - 1; i >= 0; i--) {
+                final ProcessRecord app = mService.mAm.mLruProcesses.get(i);
                 if (!app.pkgList.containsKey(packageName)) {
                     continue;
                 }
@@ -346,10 +346,10 @@
         }
     }
 
-    void saveCompatModes() {
+    private void saveCompatModes() {
         HashMap<String, Integer> pkgs;
-        synchronized (mService) {
-            pkgs = new HashMap<String, Integer>(mPackages);
+        synchronized (mService.mGlobalLock) {
+            pkgs = new HashMap<>(mPackages);
         }
 
         FileOutputStream fos = null;
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..09c152e 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -55,6 +55,7 @@
         // add other system settings here...
 
         sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.ANGLE_ENABLED_APP, String.class);
         // add other global settings here...
     }
 
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index ed891df..09064f2 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -87,14 +87,11 @@
 # User switched
 30041 am_switch_user (id|1|5)
 
-# Activity fully drawn time
-30042 am_activity_fully_drawn_time (User|1|5),(Token|1|5),(Component Name|3),(time|2|3)
-
 # Activity set to resumed
 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 ee4e36f..cfe2829 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -29,16 +29,20 @@
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
 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.KeyguardControllerProto.KEYGUARD_OCCLUDED;
+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;
+import static com.android.server.am.KeyguardOccludedProto.KEYGUARD_OCCLUDED;
 
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Trace;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
@@ -58,19 +62,18 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_AM;
 
-    private final ActivityTaskManagerService mService;
     private final ActivityStackSupervisor mStackSupervisor;
     private WindowManagerService mWindowManager;
     private boolean mKeyguardShowing;
     private boolean mAodShowing;
     private boolean mKeyguardGoingAway;
-    private boolean mOccluded;
     private boolean mDismissalRequested;
-    private ActivityRecord mDismissingKeyguardActivity;
     private int mBeforeUnoccludeTransit;
     private int mVisibilityTransactionDepth;
-    private SleepToken mSleepToken;
+    // TODO(b/111955725): Support multiple external displays
     private int mSecondaryDisplayShowing = INVALID_DISPLAY;
+    private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
+    private final ActivityTaskManagerService mService;
 
     KeyguardController(ActivityTaskManagerService service,
             ActivityStackSupervisor stackSupervisor) {
@@ -87,8 +90,8 @@
      *         on the given display, false otherwise
      */
     boolean isKeyguardOrAodShowing(int displayId) {
-        return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway &&
-                (displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
+        return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway
+                && !isDisplayOccluded(displayId);
     }
 
     /**
@@ -96,8 +99,7 @@
      *         display, false otherwise
      */
     boolean isKeyguardShowing(int displayId) {
-        return mKeyguardShowing && !mKeyguardGoingAway &&
-                (displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
+        return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId);
     }
 
     /**
@@ -133,6 +135,7 @@
         if (showingChanged) {
             dismissDockedStackIfNeeded();
             setKeyguardGoingAway(false);
+            // TODO(b/113840485): Check usage for non-default display
             mWindowManager.setKeyguardOrAodShowingOnDefaultDisplay(
                     isKeyguardOrAodShowing(DEFAULT_DISPLAY));
             if (keyguardShowing) {
@@ -248,7 +251,8 @@
         // already the dismissing activity, in which case we don't allow it to repeatedly dismiss
         // Keyguard.
         return dismissKeyguard && canDismissKeyguard() && !mAodShowing
-                && (mDismissalRequested || r != mDismissingKeyguardActivity);
+                && (mDismissalRequested
+                || getDisplay(r.getDisplayId()).mDismissingKeyguardActivity != r);
     }
 
     /**
@@ -259,44 +263,16 @@
     }
 
     private void visibilitiesUpdated() {
-        final boolean lastOccluded = mOccluded;
-        final ActivityRecord lastDismissingKeyguardActivity = mDismissingKeyguardActivity;
-        mOccluded = false;
-        mDismissingKeyguardActivity = null;
-
+        boolean requestDismissKeyguard = false;
         for (int displayNdx = mStackSupervisor.getChildCount() - 1; displayNdx >= 0; displayNdx--) {
             final ActivityDisplay display = mStackSupervisor.getChildAt(displayNdx);
-            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getChildAt(stackNdx);
-
-                // Only the top activity of the focused stack on the default display may control
-                // occluded state.
-                if (display.mDisplayId == DEFAULT_DISPLAY
-                        && mStackSupervisor.isTopDisplayFocusedStack(stack)) {
-
-                    // A dismissing activity occludes Keyguard in the insecure case for legacy
-                    // reasons.
-                    final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
-                    mOccluded =
-                            stack.topActivityOccludesKeyguard()
-                                    || (topDismissing != null
-                                            && stack.topRunningActivityLocked() == topDismissing
-                                            && canShowWhileOccluded(
-                                                    true /* dismissKeyguard */,
-                                                    false /* showWhenLocked */));
-                }
-
-                if (mDismissingKeyguardActivity == null
-                        && stack.getTopDismissingKeyguardActivity() != null) {
-                    mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity();
-                }
-            }
+            final KeyguardDisplayState state = getDisplay(display.mDisplayId);
+            state.visibilitiesUpdated(this, display);
+            requestDismissKeyguard |= state.mRequestDismissKeyguard;
         }
-        mOccluded |= mWindowManager.isShowingDream();
-        if (mOccluded != lastOccluded) {
-            handleOccludedChanged();
-        }
-        if (mDismissingKeyguardActivity != lastDismissingKeyguardActivity) {
+
+        // Dismissing Keyguard happens globally using the information from all displays.
+        if (requestDismissKeyguard) {
             handleDismissKeyguard();
         }
     }
@@ -305,7 +281,7 @@
      * Called when occluded state changed.
      */
     private void handleOccludedChanged() {
-        mWindowManager.onKeyguardOccludedChanged(mOccluded);
+        mWindowManager.onKeyguardOccludedChanged(isDisplayOccluded(DEFAULT_DISPLAY));
         if (isKeyguardLocked()) {
             mWindowManager.deferSurfaceLayout();
             try {
@@ -322,14 +298,13 @@
     }
 
     /**
-     * Called when somebody might want to dismiss the Keyguard.
+     * Called when somebody wants to dismiss the Keyguard via the flag.
      */
     private void handleDismissKeyguard() {
         // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy
         // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the
         // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded.
-        if (!mOccluded && mDismissingKeyguardActivity != null
-                && mWindowManager.isKeyguardSecure()) {
+        if (mWindowManager.isKeyguardSecure()) {
             mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
             mDismissalRequested = true;
 
@@ -345,6 +320,10 @@
         }
     }
 
+    private boolean isDisplayOccluded(int displayId) {
+        return getDisplay(displayId).mOccluded;
+    }
+
     /**
      * @return true if Keyguard can be currently dismissed without entering credentials.
      */
@@ -355,12 +334,14 @@
     private int resolveOccludeTransit() {
         if (mBeforeUnoccludeTransit != TRANSIT_UNSET
                 && mWindowManager.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
-                && mOccluded) {
+                // TODO(b/113840485): Handle app transition for individual display.
+                && isDisplayOccluded(DEFAULT_DISPLAY)) {
 
             // Reuse old transit in case we are occluding Keyguard again, meaning that we never
             // actually occclude/unocclude Keyguard, but just run a normal transition.
             return mBeforeUnoccludeTransit;
-        } else if (!mOccluded) {
+            // TODO(b/113840485): Handle app transition for individual display.
+        } else if (!isDisplayOccluded(DEFAULT_DISPLAY)) {
 
             // Save transit in case we dismiss/occlude Keyguard shortly after.
             mBeforeUnoccludeTransit = mWindowManager.getPendingAppTransition();
@@ -371,7 +352,8 @@
     }
 
     private void dismissDockedStackIfNeeded() {
-        if (mKeyguardShowing && mOccluded) {
+        // TODO(b/113840485): Handle docked stack for individual display.
+        if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) {
             // The lock screen is currently showing, but is occluded by a window that can
             // show on top of the lock screen. In this can we want to dismiss the docked
             // stack since it will be complicated/risky to try to put the activity on top
@@ -386,11 +368,116 @@
     }
 
     private void updateKeyguardSleepToken() {
-        if (mSleepToken == null && isKeyguardOrAodShowing(DEFAULT_DISPLAY)) {
-            mSleepToken = mService.acquireSleepToken("Keyguard", DEFAULT_DISPLAY);
-        } else if (mSleepToken != null && !isKeyguardOrAodShowing(DEFAULT_DISPLAY)) {
-            mSleepToken.release();
-            mSleepToken = null;
+        for (int displayNdx = mStackSupervisor.getChildCount() - 1; displayNdx >= 0; displayNdx--) {
+            final ActivityDisplay display = mStackSupervisor.getChildAt(displayNdx);
+            final KeyguardDisplayState state = getDisplay(display.mDisplayId);
+            if (isKeyguardOrAodShowing(display.mDisplayId) && state.mSleepToken == null) {
+                state.acquiredSleepToken();
+            } else if (!isKeyguardOrAodShowing(display.mDisplayId) && state.mSleepToken != null) {
+                state.releaseSleepToken();
+            }
+        }
+    }
+
+    private KeyguardDisplayState getDisplay(int displayId) {
+        if (mDisplayStates.get(displayId) == null) {
+            mDisplayStates.append(displayId,
+                    new KeyguardDisplayState(mService, displayId));
+        }
+        return mDisplayStates.get(displayId);
+    }
+
+    void onDisplayRemoved(int displayId) {
+        if (mDisplayStates.get(displayId) != null) {
+            mDisplayStates.get(displayId).onRemoved();
+            mDisplayStates.remove(displayId);
+        }
+    }
+
+    /** Represents Keyguard state per individual display. */
+    private static class KeyguardDisplayState {
+        private final int mDisplayId;
+        private boolean mOccluded;
+        private ActivityRecord mDismissingKeyguardActivity;
+        private boolean mRequestDismissKeyguard;
+        private final ActivityTaskManagerService mService;
+        private SleepToken mSleepToken;
+
+        KeyguardDisplayState(ActivityTaskManagerService service, int displayId) {
+            mService = service;
+            mDisplayId = displayId;
+        }
+
+        void onRemoved() {
+            mDismissingKeyguardActivity = null;
+            releaseSleepToken();
+        }
+
+        void acquiredSleepToken() {
+            if (mSleepToken == null) {
+                mSleepToken = mService.acquireSleepToken("keyguard", mDisplayId);
+            }
+        }
+
+        void releaseSleepToken() {
+            if (mSleepToken != null) {
+                mSleepToken.release();
+                mSleepToken = null;
+            }
+        }
+
+        void visibilitiesUpdated(KeyguardController controller, ActivityDisplay display) {
+            final boolean lastOccluded = mOccluded;
+            final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity;
+            mRequestDismissKeyguard = false;
+            mOccluded = false;
+            mDismissingKeyguardActivity = null;
+
+            // Only the top activity of the focused stack on each display may control it's
+            // occluded state.
+            final ActivityStack focusedStack = display.getFocusedStack();
+            if (focusedStack != null) {
+                final ActivityRecord topDismissing =
+                        focusedStack.getTopDismissingKeyguardActivity();
+                mOccluded = focusedStack.topActivityOccludesKeyguard() || (topDismissing != null
+                                && focusedStack.topRunningActivityLocked() == topDismissing
+                                && controller.canShowWhileOccluded(
+                                true /* dismissKeyguard */,
+                                false /* showWhenLocked */));
+                if (focusedStack.getTopDismissingKeyguardActivity() != null) {
+                    mDismissingKeyguardActivity = focusedStack.getTopDismissingKeyguardActivity();
+                }
+                mOccluded |= controller.mWindowManager.isShowingDream();
+            }
+
+            // TODO(b/113840485): Handle app transition for individual display.
+            // For now, only default display can change occluded.
+            if (lastOccluded != mOccluded && mDisplayId == DEFAULT_DISPLAY) {
+                controller.handleOccludedChanged();
+            }
+            if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
+                    && mDismissingKeyguardActivity != null
+                    && controller.mWindowManager.isKeyguardSecure()) {
+                mRequestDismissKeyguard = true;
+            }
+        }
+
+        void dumpStatus(PrintWriter pw, String prefix) {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(prefix);
+            sb.append("  Occluded=").append(mOccluded)
+                    .append(" DismissingKeyguardActivity=")
+                    .append(mDismissingKeyguardActivity)
+                    .append(" at display=")
+                    .append(mDisplayId);
+            pw.println(sb.toString());
+        }
+
+        void writeToProto(ProtoOutputStream proto, long fieldId) {
+            final long token = proto.start(fieldId);
+            proto.write(DISPLAY_ID, mDisplayId);
+            proto.write(KEYGUARD_OCCLUDED, mOccluded);
+            proto.end(token);
         }
     }
 
@@ -399,8 +486,7 @@
         pw.println(prefix + "  mKeyguardShowing=" + mKeyguardShowing);
         pw.println(prefix + "  mAodShowing=" + mAodShowing);
         pw.println(prefix + "  mKeyguardGoingAway=" + mKeyguardGoingAway);
-        pw.println(prefix + "  mOccluded=" + mOccluded);
-        pw.println(prefix + "  mDismissingKeyguardActivity=" + mDismissingKeyguardActivity);
+        dumpDisplayStates(pw, prefix);
         pw.println(prefix + "  mDismissalRequested=" + mDismissalRequested);
         pw.println(prefix + "  mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
     }
@@ -408,7 +494,19 @@
     void writeToProto(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(KEYGUARD_SHOWING, mKeyguardShowing);
-        proto.write(KEYGUARD_OCCLUDED, mOccluded);
+        writeDisplayStatesToProto(proto, KEYGUARD_OCCLUDED_STATES);
         proto.end(token);
     }
+
+    private void dumpDisplayStates(PrintWriter pw, String prefix) {
+        for (int i = 0; i < mDisplayStates.size(); i++) {
+            mDisplayStates.valueAt(i).dumpStatus(pw, prefix);
+        }
+    }
+
+    private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) {
+        for (int i = 0; i < mDisplayStates.size(); i++) {
+            mDisplayStates.valueAt(i).writeToProto(proto, fieldId);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/LaunchTimeTracker.java b/services/core/java/com/android/server/am/LaunchTimeTracker.java
deleted file mode 100644
index ee86969..0000000
--- a/services/core/java/com/android/server/am/LaunchTimeTracker.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.am;
-
-import android.app.WaitResult;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.util.SparseArray;
-
-/**
- * Tracks launch time of apps to be reported by {@link WaitResult}. Note that this is slightly
- * different from {@link ActivityMetricsLogger}, but should eventually merged with it.
- */
-class LaunchTimeTracker {
-
-    private final SparseArray<Entry> mWindowingModeLaunchTime = new SparseArray<>();
-
-    void setLaunchTime(ActivityRecord r) {
-        Entry entry = mWindowingModeLaunchTime.get(r.getWindowingMode());
-        if (entry == null){
-            entry = new Entry();
-            mWindowingModeLaunchTime.append(r.getWindowingMode(), entry);
-        }
-        entry.setLaunchTime(r);
-    }
-
-    void stopFullyDrawnTraceIfNeeded(int windowingMode) {
-        final Entry entry = mWindowingModeLaunchTime.get(windowingMode);
-        if (entry == null) {
-            return;
-        }
-        entry.stopFullyDrawnTraceIfNeeded();
-    }
-
-    Entry getEntry(int windowingMode) {
-        return mWindowingModeLaunchTime.get(windowingMode);
-    }
-
-    static class Entry {
-
-        long mLaunchStartTime;
-        long mFullyDrawnStartTime;
-
-        void setLaunchTime(ActivityRecord r) {
-            if (r.displayStartTime == 0) {
-                r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
-                if (mLaunchStartTime == 0) {
-                    startLaunchTraces(r.packageName);
-                    mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
-                }
-            } else if (mLaunchStartTime == 0) {
-                startLaunchTraces(r.packageName);
-                mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
-            }
-        }
-
-        private void startLaunchTraces(String packageName) {
-            if (mFullyDrawnStartTime != 0)  {
-                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-            }
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-        }
-
-        private void stopFullyDrawnTraceIfNeeded() {
-            if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
-                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-                mFullyDrawnStartTime = 0;
-            }
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index f9dccea0..a8e1ccc 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -22,6 +22,7 @@
 
 import android.annotation.Nullable;
 import android.os.FileUtils;
+import android.os.SystemProperties;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -36,14 +37,26 @@
  * Static utility methods related to {@link MemoryStat}.
  */
 final class MemoryStatUtil {
+    static final int BYTES_IN_KILOBYTE = 1024;
+    static final int PAGE_SIZE = 4096;
+
     private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM;
 
+    /** True if device has per-app memcg */
+    private static final boolean DEVICE_HAS_PER_APP_MEMCG =
+            SystemProperties.getBoolean("ro.config.per_app_memcg", false);
+
     /** Path to check if device has memcg */
     private static final String MEMCG_TEST_PATH = "/dev/memcg/apps/memory.stat";
     /** Path to memory stat file for logging app start memory state */
     private static final String MEMORY_STAT_FILE_FMT = "/dev/memcg/apps/uid_%d/pid_%d/memory.stat";
+    /** Path to memory max usage file for logging app memory state */
+    private static final String MEMORY_MAX_USAGE_FILE_FMT =
+            "/dev/memcg/apps/uid_%d/pid_%d/memory.max_usage_in_bytes";
     /** Path to procfs stat file for logging app start memory state */
     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";
 
     private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)");
     private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)");
@@ -51,19 +64,19 @@
     private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)");
     private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)");
 
+    private static final Pattern RSS_HIGH_WATERMARK_IN_BYTES =
+            Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB");
+
     private static final int PGFAULT_INDEX = 9;
     private static final int PGMAJFAULT_INDEX = 11;
-    private static final int RSS_IN_BYTES_INDEX = 23;
-
-    /** True if device has memcg */
-    private static volatile Boolean sDeviceHasMemCg;
+    private static final int RSS_IN_PAGES_INDEX = 23;
 
     private MemoryStatUtil() {}
 
     /**
      * Reads memory stat for a process.
      *
-     * Reads from memcg if available on device, else fallback to procfs.
+     * Reads from per-app memcg if available on device, else fallback to procfs.
      * Returns null if no stats can be read.
      */
     @Nullable
@@ -78,8 +91,15 @@
      */
     @Nullable
     static MemoryStat readMemoryStatFromMemcg(int uid, int pid) {
-        final String path = String.format(Locale.US, MEMORY_STAT_FILE_FMT, uid, pid);
-        return parseMemoryStatFromMemcg(readFileContents(path));
+        final String statPath = String.format(Locale.US, MEMORY_STAT_FILE_FMT, uid, pid);
+        MemoryStat stat = parseMemoryStatFromMemcg(readFileContents(statPath));
+        if (stat == null) {
+            return null;
+        }
+        String maxUsagePath = String.format(Locale.US, MEMORY_MAX_USAGE_FILE_FMT, uid, pid);
+        stat.rssHighWatermarkInBytes = parseMemoryMaxUsageFromMemCg(
+                readFileContents(maxUsagePath));
+        return stat;
     }
 
     /**
@@ -89,8 +109,14 @@
      */
     @Nullable
     static MemoryStat readMemoryStatFromProcfs(int pid) {
-        final String path = String.format(Locale.US, PROC_STAT_FILE_FMT, pid);
-        return parseMemoryStatFromProcfs(readFileContents(path));
+        final String statPath = String.format(Locale.US, PROC_STAT_FILE_FMT, pid);
+        MemoryStat stat = parseMemoryStatFromProcfs(readFileContents(statPath));
+        if (stat == null) {
+            return null;
+        }
+        final String statusPath = String.format(Locale.US, PROC_STATUS_FILE_FMT, pid);
+        stat.rssHighWatermarkInBytes = parseVmHWMFromProcfs(readFileContents(statusPath));
+        return stat;
     }
 
     private static String readFileContents(String path) {
@@ -111,7 +137,7 @@
     /**
      * Parses relevant statistics out from the contents of a memory.stat file in memcg.
      */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    @VisibleForTesting
     @Nullable
     static MemoryStat parseMemoryStatFromMemcg(String memoryStatContents) {
         if (memoryStatContents == null || memoryStatContents.isEmpty()) {
@@ -121,22 +147,35 @@
         final MemoryStat memoryStat = new MemoryStat();
         Matcher m;
         m = PGFAULT.matcher(memoryStatContents);
-        memoryStat.pgfault = m.find() ? Long.valueOf(m.group(1)) : 0;
+        memoryStat.pgfault = m.find() ? Long.parseLong(m.group(1)) : 0;
         m = PGMAJFAULT.matcher(memoryStatContents);
-        memoryStat.pgmajfault = m.find() ? Long.valueOf(m.group(1)) : 0;
+        memoryStat.pgmajfault = m.find() ? Long.parseLong(m.group(1)) : 0;
         m = RSS_IN_BYTES.matcher(memoryStatContents);
-        memoryStat.rssInBytes = m.find() ? Long.valueOf(m.group(1)) : 0;
+        memoryStat.rssInBytes = m.find() ? Long.parseLong(m.group(1)) : 0;
         m = CACHE_IN_BYTES.matcher(memoryStatContents);
-        memoryStat.cacheInBytes = m.find() ? Long.valueOf(m.group(1)) : 0;
+        memoryStat.cacheInBytes = m.find() ? Long.parseLong(m.group(1)) : 0;
         m = SWAP_IN_BYTES.matcher(memoryStatContents);
-        memoryStat.swapInBytes = m.find() ? Long.valueOf(m.group(1)) : 0;
+        memoryStat.swapInBytes = m.find() ? Long.parseLong(m.group(1)) : 0;
         return memoryStat;
     }
 
+    @VisibleForTesting
+    static long parseMemoryMaxUsageFromMemCg(String memoryMaxUsageContents) {
+        if (memoryMaxUsageContents == null || memoryMaxUsageContents.isEmpty()) {
+            return 0;
+        }
+        try {
+            return Long.parseLong(memoryMaxUsageContents);
+        } catch (NumberFormatException e) {
+            Slog.e(TAG, "Failed to parse value", e);
+            return 0;
+        }
+    }
+
     /**
-     * Parses relevant statistics out from the contents of a /proc/pid/stat file in procfs.
+     * Parses relevant statistics out from the contents of the /proc/pid/stat file in procfs.
      */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    @VisibleForTesting
     @Nullable
     static MemoryStat parseMemoryStatFromProcfs(String procStatContents) {
         if (procStatContents == null || procStatContents.isEmpty()) {
@@ -148,23 +187,37 @@
             return null;
         }
 
-        final MemoryStat memoryStat = new MemoryStat();
-        memoryStat.pgfault = Long.valueOf(splits[PGFAULT_INDEX]);
-        memoryStat.pgmajfault = Long.valueOf(splits[PGMAJFAULT_INDEX]);
-        memoryStat.rssInBytes = Long.valueOf(splits[RSS_IN_BYTES_INDEX]);
-        return memoryStat;
+        try {
+            final MemoryStat memoryStat = new MemoryStat();
+            memoryStat.pgfault = Long.parseLong(splits[PGFAULT_INDEX]);
+            memoryStat.pgmajfault = Long.parseLong(splits[PGMAJFAULT_INDEX]);
+            memoryStat.rssInBytes = Long.parseLong(splits[RSS_IN_PAGES_INDEX]) * PAGE_SIZE;
+            return memoryStat;
+        } catch (NumberFormatException e) {
+            Slog.e(TAG, "Failed to parse value", e);
+            return null;
+        }
     }
 
     /**
-     * Checks if memcg is available on device.
-     *
-     * Touches the filesystem to do the check.
+     * Parses RSS high watermark out from the contents of the /proc/pid/status file in procfs. The
+     * returned value is in bytes.
+     */
+    @VisibleForTesting
+    static long parseVmHWMFromProcfs(String procStatusContents) {
+        if (procStatusContents == null || procStatusContents.isEmpty()) {
+            return 0;
+        }
+        Matcher m = RSS_HIGH_WATERMARK_IN_BYTES.matcher(procStatusContents);
+        // Convert value read from /proc/pid/status from kilobytes to bytes.
+        return m.find() ? Long.parseLong(m.group(1)) * BYTES_IN_KILOBYTE : 0;
+    }
+
+    /**
+     * Returns whether per-app memcg is available on device.
      */
     static boolean hasMemcg() {
-        if (sDeviceHasMemCg == null) {
-            sDeviceHasMemCg = (new File(MEMCG_TEST_PATH)).exists();
-        }
-        return sDeviceHasMemCg;
+        return DEVICE_HAS_PER_APP_MEMCG;
     }
 
     static final class MemoryStat {
@@ -178,5 +231,7 @@
         long cacheInBytes;
         /** Number of bytes of swap usage */
         long swapInBytes;
+        /** Number of bytes of peak anonymous and swap cache memory */
+        long rssHighWatermarkInBytes;
     }
 }
diff --git a/services/core/java/com/android/server/am/OomAdjProfiler.java b/services/core/java/com/android/server/am/OomAdjProfiler.java
index 6230e0d..71f0db5 100644
--- a/services/core/java/com/android/server/am/OomAdjProfiler.java
+++ b/services/core/java/com/android/server/am/OomAdjProfiler.java
@@ -91,9 +91,9 @@
                 return;
             }
             mSystemServerCpuTimeUpdateScheduled = true;
-            BackgroundThread.getHandler().post(PooledLambda.obtainRunnable(
+            BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
                     OomAdjProfiler::updateSystemServerCpuTime,
-                    this, mOnBattery, mScreenOff).recycleOnUse());
+                    this, mOnBattery, mScreenOff));
         }
     }
 
diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java
new file mode 100644
index 0000000..a9c00a7
--- /dev/null
+++ b/services/core/java/com/android/server/am/PendingIntentController.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.app.Activity;
+import android.app.ActivityManagerInternal;
+import android.app.AppGlobals;
+import android.app.PendingIntent;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.Slog;
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.LocalServices;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Helper class for {@link ActivityManagerService} responsible for managing pending intents.
+ *
+ * <p>This class uses {@link #mLock} to synchronize access to internal state and doesn't make use of
+ * {@link ActivityManagerService} lock since there can be direct calls into this class from outside
+ * AM. This helps avoid deadlocks.
+ */
+public class PendingIntentController {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentController" : TAG_AM;
+    private static final String TAG_MU = TAG + POSTFIX_MU;
+
+    /** Lock for internal state. */
+    final Object mLock = new Object();
+    final Handler mH;
+    ActivityManagerInternal mAmInternal;
+    final UserController mUserController;
+    final ActivityTaskManagerInternal mAtmInternal;
+
+    /** Set of IntentSenderRecord objects that are currently active. */
+    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
+            = new HashMap<>();
+
+    PendingIntentController(Looper looper, UserController userController) {
+        mH = new Handler(looper);
+        mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
+        mUserController = userController;
+    }
+
+    void onActivityManagerInternalAdded() {
+        synchronized (mLock) {
+            mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
+        }
+    }
+
+    PendingIntentRecord getIntentSender(int type, String packageName, int callingUid, int userId,
+            IBinder token, String resultWho, int requestCode, Intent[] intents,
+            String[] resolvedTypes, int flags, Bundle bOptions) {
+        synchronized (mLock) {
+            if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSender(): uid=" + callingUid);
+
+            // We're going to be splicing together extras before sending, so we're
+            // okay poking into any contained extras.
+            if (intents != null) {
+                for (int i = 0; i < intents.length; i++) {
+                    intents[i].setDefusable(true);
+                }
+            }
+            Bundle.setDefusable(bOptions, true);
+
+            final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
+            final boolean cancelCurrent = (flags & PendingIntent.FLAG_CANCEL_CURRENT) != 0;
+            final boolean updateCurrent = (flags & PendingIntent.FLAG_UPDATE_CURRENT) != 0;
+            flags &= ~(PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_CANCEL_CURRENT
+                    | PendingIntent.FLAG_UPDATE_CURRENT);
+
+            PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, token,
+                    resultWho, requestCode, intents, resolvedTypes, flags,
+                    SafeActivityOptions.fromBundle(bOptions), userId);
+            WeakReference<PendingIntentRecord> ref;
+            ref = mIntentSenderRecords.get(key);
+            PendingIntentRecord rec = ref != null ? ref.get() : null;
+            if (rec != null) {
+                if (!cancelCurrent) {
+                    if (updateCurrent) {
+                        if (rec.key.requestIntent != null) {
+                            rec.key.requestIntent.replaceExtras(intents != null ?
+                                    intents[intents.length - 1] : null);
+                        }
+                        if (intents != null) {
+                            intents[intents.length - 1] = rec.key.requestIntent;
+                            rec.key.allIntents = intents;
+                            rec.key.allResolvedTypes = resolvedTypes;
+                        } else {
+                            rec.key.allIntents = null;
+                            rec.key.allResolvedTypes = null;
+                        }
+                    }
+                    return rec;
+                }
+                makeIntentSenderCanceled(rec);
+                mIntentSenderRecords.remove(key);
+            }
+            if (noCreate) {
+                return rec;
+            }
+            rec = new PendingIntentRecord(this, key, callingUid);
+            mIntentSenderRecords.put(key, rec.ref);
+            return rec;
+        }
+    }
+
+    boolean removePendingIntentsForPackage(String packageName, int userId, int appId,
+            boolean doIt) {
+
+        boolean didSomething = false;
+        synchronized (mLock) {
+
+            // Remove pending intents.  For now we only do this when force stopping users, because
+            // we have some problems when doing this for packages -- app widgets are not currently
+            // cleaned up for such packages, so they can be left with bad pending intents.
+            if (mIntentSenderRecords.size() <= 0) {
+                return false;
+            }
+
+            Iterator<WeakReference<PendingIntentRecord>> it
+                    = mIntentSenderRecords.values().iterator();
+            while (it.hasNext()) {
+                WeakReference<PendingIntentRecord> wpir = it.next();
+                if (wpir == null) {
+                    it.remove();
+                    continue;
+                }
+                PendingIntentRecord pir = wpir.get();
+                if (pir == null) {
+                    it.remove();
+                    continue;
+                }
+                if (packageName == null) {
+                    // Stopping user, remove all objects for the user.
+                    if (pir.key.userId != userId) {
+                        // Not the same user, skip it.
+                        continue;
+                    }
+                } else {
+                    if (UserHandle.getAppId(pir.uid) != appId) {
+                        // Different app id, skip it.
+                        continue;
+                    }
+                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
+                        // Different user, skip it.
+                        continue;
+                    }
+                    if (!pir.key.packageName.equals(packageName)) {
+                        // Different package, skip it.
+                        continue;
+                    }
+                }
+                if (!doIt) {
+                    return true;
+                }
+                didSomething = true;
+                it.remove();
+                makeIntentSenderCanceled(pir);
+                if (pir.key.activity != null) {
+                    final Message m = PooledLambda.obtainMessage(
+                            PendingIntentController::clearPendingResultForActivity, this,
+                            pir.key.activity, pir.ref);
+                    mH.sendMessage(m);
+                }
+            }
+        }
+
+        return didSomething;
+    }
+
+    public void cancelIntentSender(IIntentSender sender) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        synchronized (mLock) {
+            final PendingIntentRecord rec = (PendingIntentRecord) sender;
+            try {
+                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
+                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
+                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
+                    String msg = "Permission Denial: cancelIntentSender() from pid="
+                            + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                            + " is not allowed to cancel package " + rec.key.packageName;
+                    Slog.w(TAG, msg);
+                    throw new SecurityException(msg);
+                }
+            } catch (RemoteException e) {
+                throw new SecurityException(e);
+            }
+            cancelIntentSender(rec, true);
+        }
+    }
+
+    public void cancelIntentSender(PendingIntentRecord rec, boolean cleanActivity) {
+        synchronized (mLock) {
+            makeIntentSenderCanceled(rec);
+            mIntentSenderRecords.remove(rec.key);
+            if (cleanActivity && rec.key.activity != null) {
+                final Message m = PooledLambda.obtainMessage(
+                        PendingIntentController::clearPendingResultForActivity, this,
+                        rec.key.activity, rec.ref);
+                mH.sendMessage(m);
+            }
+        }
+    }
+
+    private void makeIntentSenderCanceled(PendingIntentRecord rec) {
+        rec.canceled = true;
+        final RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
+        if (callbacks != null) {
+            final Message m = PooledLambda.obtainMessage(
+                    PendingIntentController::handlePendingIntentCancelled, this, callbacks);
+            mH.sendMessage(m);
+        }
+    }
+
+    private void handlePendingIntentCancelled(RemoteCallbackList<IResultReceiver> callbacks) {
+        int N = callbacks.beginBroadcast();
+        for (int i = 0; i < N; i++) {
+            try {
+                callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
+            } catch (RemoteException e) {
+                // Process is not longer running...whatever.
+            }
+        }
+        callbacks.finishBroadcast();
+        // We have to clean up the RemoteCallbackList here, because otherwise it will
+        // needlessly hold the enclosed callbacks until the remote process dies.
+        callbacks.kill();
+    }
+
+    private void clearPendingResultForActivity(IBinder activityToken,
+            WeakReference<PendingIntentRecord> pir) {
+        mAtmInternal.clearPendingResultForActivity(activityToken, pir);
+    }
+
+    void dumpPendingIntents(PrintWriter pw, boolean dumpAll, String dumpPackage) {
+        synchronized (mLock) {
+            boolean printed = false;
+
+            pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
+
+            if (mIntentSenderRecords.size() > 0) {
+                // Organize these by package name, so they are easier to read.
+                final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
+                final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
+                final Iterator<WeakReference<PendingIntentRecord>> it
+                        = mIntentSenderRecords.values().iterator();
+                while (it.hasNext()) {
+                    WeakReference<PendingIntentRecord> ref = it.next();
+                    PendingIntentRecord rec = ref != null ? ref.get() : null;
+                    if (rec == null) {
+                        weakRefs.add(ref);
+                        continue;
+                    }
+                    if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
+                        continue;
+                    }
+                    ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
+                    if (list == null) {
+                        list = new ArrayList<>();
+                        byPackage.put(rec.key.packageName, list);
+                    }
+                    list.add(rec);
+                }
+                for (int i = 0; i < byPackage.size(); i++) {
+                    ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
+                    printed = true;
+                    pw.print("  * "); pw.print(byPackage.keyAt(i));
+                    pw.print(": "); pw.print(intents.size()); pw.println(" items");
+                    for (int j = 0; j < intents.size(); j++) {
+                        pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
+                        if (dumpAll) {
+                            intents.get(j).dump(pw, "      ");
+                        }
+                    }
+                }
+                if (weakRefs.size() > 0) {
+                    printed = true;
+                    pw.println("  * WEAK REFS:");
+                    for (int i = 0; i < weakRefs.size(); i++) {
+                        pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
+                    }
+                }
+            }
+
+            if (!printed) {
+                pw.println("  (nothing)");
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index ee1166e..b9c6fa6 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -38,15 +38,16 @@
 import android.util.TimeUtils;
 
 import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.Objects;
 
-final class PendingIntentRecord extends IIntentSender.Stub {
+public final class PendingIntentRecord extends IIntentSender.Stub {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentRecord" : TAG_AM;
 
-    final ActivityManagerService owner;
+    final PendingIntentController controller;
     final Key key;
     final int uid;
     final WeakReference<PendingIntentRecord> ref;
@@ -62,7 +63,7 @@
     final static class Key {
         final int type;
         final String packageName;
-        final ActivityRecord activity;
+        final IBinder activity;
         final String who;
         final int requestCode;
         final Intent requestIntent;
@@ -76,7 +77,7 @@
 
         private static final int ODD_PRIME_NUMBER = 37;
 
-        Key(int _t, String _p, ActivityRecord _a, String _w,
+        Key(int _t, String _p, IBinder _a, String _w,
                 int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId) {
             type = _t;
             packageName = _p;
@@ -114,6 +115,7 @@
             //        + Integer.toHexString(hashCode));
         }
 
+        @Override
         public boolean equals(Object otherObj) {
             if (otherObj == null) {
                 return false;
@@ -188,11 +190,11 @@
         }
     }
 
-    PendingIntentRecord(ActivityManagerService _owner, Key _k, int _u) {
-        owner = _owner;
+    PendingIntentRecord(PendingIntentController _controller, Key _k, int _u) {
+        controller = _controller;
         key = _k;
         uid = _u;
-        ref = new WeakReference<PendingIntentRecord>(this);
+        ref = new WeakReference<>(this);
     }
 
     void setWhitelistDurationLocked(IBinder whitelistToken, long duration) {
@@ -247,189 +249,196 @@
     }
 
     int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken,
-            IIntentReceiver finishedReceiver,
-            String requiredPermission, IBinder resultTo, String resultWho, int requestCode,
-            int flagsMask, int flagsValues, Bundle options) {
+            IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo,
+            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) {
         if (intent != null) intent.setDefusable(true);
         if (options != null) options.setDefusable(true);
 
-        synchronized (owner) {
-            if (!canceled) {
-                sent = true;
-                if ((key.flags&PendingIntent.FLAG_ONE_SHOT) != 0) {
-                    owner.cancelIntentSenderLocked(this, true);
-                }
+        Long duration = null;
+        Intent finalIntent = null;
+        Intent[] allIntents = null;
+        String[] allResolvedTypes = null;
+        SafeActivityOptions mergedOptions = null;
+        synchronized (controller.mLock) {
+            if (canceled) {
+                return ActivityManager.START_CANCELED;
+            }
 
-                Intent finalIntent = key.requestIntent != null
-                        ? new Intent(key.requestIntent) : new Intent();
+            sent = true;
+            if ((key.flags & PendingIntent.FLAG_ONE_SHOT) != 0) {
+                controller.cancelIntentSender(this, true);
+            }
 
-                final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0;
-                if (!immutable) {
-                    if (intent != null) {
-                        int changes = finalIntent.fillIn(intent, key.flags);
-                        if ((changes & Intent.FILL_IN_DATA) == 0) {
-                            resolvedType = key.requestResolvedType;
-                        }
-                    } else {
+            finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent();
+
+            final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0;
+            if (!immutable) {
+                if (intent != null) {
+                    int changes = finalIntent.fillIn(intent, key.flags);
+                    if ((changes & Intent.FILL_IN_DATA) == 0) {
                         resolvedType = key.requestResolvedType;
                     }
-                    flagsMask &= ~Intent.IMMUTABLE_FLAGS;
-                    flagsValues &= flagsMask;
-                    finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues);
                 } else {
                     resolvedType = key.requestResolvedType;
                 }
-
-                final int callingUid = Binder.getCallingUid();
-                final int callingPid = Binder.getCallingPid();
-
-                // Extract options before clearing calling identity
-                SafeActivityOptions mergedOptions = key.options;
-                if (mergedOptions == null) {
-                    mergedOptions = SafeActivityOptions.fromBundle(options);
-                } else {
-                    mergedOptions.setCallerOptions(ActivityOptions.fromBundle(options));
-                }
-
-                final long origId = Binder.clearCallingIdentity();
-
-                if (whitelistDuration != null) {
-                    Long duration = whitelistDuration.get(whitelistToken);
-                    if (duration != null) {
-                        int procState = owner.getUidState(callingUid);
-                        if (!ActivityManager.isProcStateBackground(procState)) {
-                            StringBuilder tag = new StringBuilder(64);
-                            tag.append("pendingintent:");
-                            UserHandle.formatUid(tag, callingUid);
-                            tag.append(":");
-                            if (finalIntent.getAction() != null) {
-                                tag.append(finalIntent.getAction());
-                            } else if (finalIntent.getComponent() != null) {
-                                finalIntent.getComponent().appendShortString(tag);
-                            } else if (finalIntent.getData() != null) {
-                                tag.append(finalIntent.getData().toSafeString());
-                            }
-                            owner.tempWhitelistForPendingIntentLocked(callingPid,
-                                    callingUid, uid, duration, tag.toString());
-                        } else {
-                            Slog.w(TAG, "Not doing whitelist " + this + ": caller state="
-                                    + procState);
-                        }
-                    }
-                }
-
-                boolean sendFinish = finishedReceiver != null;
-                int userId = key.userId;
-                if (userId == UserHandle.USER_CURRENT) {
-                    userId = owner.mUserController.getCurrentOrTargetUserId();
-                }
-                int res = START_SUCCESS;
-                switch (key.type) {
-                    case ActivityManager.INTENT_SENDER_ACTIVITY:
-                        try {
-                            // Note when someone has a pending intent, even from different
-                            // users, then there's no need to ensure the calling user matches
-                            // the target user, so validateIncomingUser is always false below.
-
-                            if (key.allIntents != null && key.allIntents.length > 1) {
-                                Intent[] allIntents = new Intent[key.allIntents.length];
-                                String[] allResolvedTypes = new String[key.allIntents.length];
-                                System.arraycopy(key.allIntents, 0, allIntents, 0,
-                                        key.allIntents.length);
-                                if (key.allResolvedTypes != null) {
-                                    System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0,
-                                            key.allResolvedTypes.length);
-                                }
-                                allIntents[allIntents.length-1] = finalIntent;
-                                allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
-
-                                res = owner.mActivityTaskManager.getActivityStartController().startActivitiesInPackage(
-                                        uid, key.packageName, allIntents, allResolvedTypes,
-                                        resultTo, mergedOptions, userId,
-                                        false /* validateIncomingUser */,
-                                        this /* originatingPendingIntent */);
-                            } else {
-                                res = owner.mActivityTaskManager.getActivityStartController().startActivityInPackage(uid,
-                                        callingPid, callingUid, key.packageName, finalIntent,
-                                        resolvedType, resultTo, resultWho, requestCode, 0,
-                                        mergedOptions, userId, null, "PendingIntentRecord",
-                                        false /* validateIncomingUser */,
-                                        this /* originatingPendingIntent */);
-                            }
-                        } catch (RuntimeException e) {
-                            Slog.w(TAG, "Unable to send startActivity intent", e);
-                        }
-                        break;
-                    case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
-                        final ActivityStack stack = key.activity.getStack();
-                        if (stack != null) {
-                            stack.sendActivityResultLocked(-1, key.activity, key.who,
-                                    key.requestCode, code, finalIntent);
-                        }
-                        break;
-                    case ActivityManager.INTENT_SENDER_BROADCAST:
-                        try {
-                            // If a completion callback has been requested, require
-                            // that the broadcast be delivered synchronously
-                            int sent = owner.broadcastIntentInPackage(key.packageName, uid,
-                                    finalIntent, resolvedType, finishedReceiver, code, null, null,
-                                    requiredPermission, options, (finishedReceiver != null),
-                                    false, userId);
-                            if (sent == ActivityManager.BROADCAST_SUCCESS) {
-                                sendFinish = false;
-                            }
-                        } catch (RuntimeException e) {
-                            Slog.w(TAG, "Unable to send startActivity intent", e);
-                        }
-                        break;
-                    case ActivityManager.INTENT_SENDER_SERVICE:
-                    case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
-                        try {
-                            owner.startServiceInPackage(uid, finalIntent, resolvedType,
-                                    key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
-                                    key.packageName, userId);
-                        } catch (RuntimeException e) {
-                            Slog.w(TAG, "Unable to send startService intent", e);
-                        } catch (TransactionTooLargeException e) {
-                            res = ActivityManager.START_CANCELED;
-                        }
-                        break;
-                }
-
-                if (sendFinish && res != ActivityManager.START_CANCELED) {
-                    try {
-                        finishedReceiver.performReceive(new Intent(finalIntent), 0,
-                                null, null, false, false, key.userId);
-                    } catch (RemoteException e) {
-                    }
-                }
-
-                Binder.restoreCallingIdentity(origId);
-
-                return res;
+                flagsMask &= ~Intent.IMMUTABLE_FLAGS;
+                flagsValues &= flagsMask;
+                finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues);
+            } else {
+                resolvedType = key.requestResolvedType;
             }
+
+            // Extract options before clearing calling identity
+            mergedOptions = key.options;
+            if (mergedOptions == null) {
+                mergedOptions = SafeActivityOptions.fromBundle(options);
+            } else {
+                mergedOptions.setCallerOptions(ActivityOptions.fromBundle(options));
+            }
+
+            if (whitelistDuration != null) {
+                duration = whitelistDuration.get(whitelistToken);
+            }
+
+            if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY
+                    && key.allIntents != null && key.allIntents.length > 1) {
+                // Copy all intents and resolved types while we have the controller lock so we can
+                // use it later when the lock isn't held.
+                allIntents = new Intent[key.allIntents.length];
+                allResolvedTypes = new String[key.allIntents.length];
+                System.arraycopy(key.allIntents, 0, allIntents, 0, key.allIntents.length);
+                if (key.allResolvedTypes != null) {
+                    System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0,
+                            key.allResolvedTypes.length);
+                }
+                allIntents[allIntents.length - 1] = finalIntent;
+                allResolvedTypes[allResolvedTypes.length - 1] = resolvedType;
+            }
+
         }
-        return ActivityManager.START_CANCELED;
+        // We don't hold the controller lock beyond this point as we will be calling into AM and WM.
+
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final long origId = Binder.clearCallingIdentity();
+
+        int res = START_SUCCESS;
+        try {
+            if (duration != null) {
+                int procState = controller.mAmInternal.getUidProcessState(callingUid);
+                if (!ActivityManager.isProcStateBackground(procState)) {
+                    StringBuilder tag = new StringBuilder(64);
+                    tag.append("pendingintent:");
+                    UserHandle.formatUid(tag, callingUid);
+                    tag.append(":");
+                    if (finalIntent.getAction() != null) {
+                        tag.append(finalIntent.getAction());
+                    } else if (finalIntent.getComponent() != null) {
+                        finalIntent.getComponent().appendShortString(tag);
+                    } else if (finalIntent.getData() != null) {
+                        tag.append(finalIntent.getData().toSafeString());
+                    }
+                    controller.mAmInternal.tempWhitelistForPendingIntent(callingPid, callingUid,
+                            uid, duration, tag.toString());
+                } else {
+                    Slog.w(TAG, "Not doing whitelist " + this + ": caller state=" + procState);
+                }
+            }
+
+            boolean sendFinish = finishedReceiver != null;
+            int userId = key.userId;
+            if (userId == UserHandle.USER_CURRENT) {
+                userId = controller.mUserController.getCurrentOrTargetUserId();
+            }
+
+            switch (key.type) {
+                case ActivityManager.INTENT_SENDER_ACTIVITY:
+                    try {
+                        // Note when someone has a pending intent, even from different
+                        // users, then there's no need to ensure the calling user matches
+                        // the target user, so validateIncomingUser is always false below.
+
+                        if (key.allIntents != null && key.allIntents.length > 1) {
+                            res = controller.mAtmInternal.startActivitiesInPackage(
+                                    uid, key.packageName, allIntents, allResolvedTypes, resultTo,
+                                    mergedOptions, userId, false /* validateIncomingUser */,
+                                    this /* originatingPendingIntent */);
+                        } else {
+                            res = controller.mAtmInternal.startActivityInPackage(
+                                    uid, callingPid, callingUid, key.packageName, finalIntent,
+                                    resolvedType, resultTo, resultWho, requestCode, 0,
+                                    mergedOptions, userId, null, "PendingIntentRecord",
+                                    false /* validateIncomingUser */,
+                                    this /* originatingPendingIntent */);
+                        }
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "Unable to send startActivity intent", e);
+                    }
+                    break;
+                case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
+                    controller.mAtmInternal.sendActivityResult(-1, key.activity, key.who,
+                                key.requestCode, code, finalIntent);
+                    break;
+                case ActivityManager.INTENT_SENDER_BROADCAST:
+                    try {
+                        // If a completion callback has been requested, require
+                        // that the broadcast be delivered synchronously
+                        int sent = controller.mAmInternal.broadcastIntentInPackage(key.packageName,
+                                uid, finalIntent, resolvedType, finishedReceiver, code, null, null,
+                                requiredPermission, options, (finishedReceiver != null),
+                                false, userId);
+                        if (sent == ActivityManager.BROADCAST_SUCCESS) {
+                            sendFinish = false;
+                        }
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "Unable to send startActivity intent", e);
+                    }
+                    break;
+                case ActivityManager.INTENT_SENDER_SERVICE:
+                case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
+                    try {
+                        controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType,
+                                key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
+                                key.packageName, userId);
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "Unable to send startService intent", e);
+                    } catch (TransactionTooLargeException e) {
+                        res = ActivityManager.START_CANCELED;
+                    }
+                    break;
+            }
+
+            if (sendFinish && res != ActivityManager.START_CANCELED) {
+                try {
+                    finishedReceiver.performReceive(new Intent(finalIntent), 0,
+                            null, null, false, false, key.userId);
+                } catch (RemoteException e) {
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+
+        return res;
     }
 
     @Override
     protected void finalize() throws Throwable {
         try {
             if (!canceled) {
-                owner.mHandler.sendMessage(owner.mHandler.obtainMessage(
-                        ActivityManagerService.FINALIZE_PENDING_INTENT_MSG, this));
+                controller.mH.sendMessage(PooledLambda.obtainMessage(
+                        PendingIntentRecord::completeFinalize, this));
             }
         } finally {
             super.finalize();
         }
     }
 
-    public void completeFinalize() {
-        synchronized(owner) {
-            WeakReference<PendingIntentRecord> current =
-                    owner.mIntentSenderRecords.get(key);
+    private void completeFinalize() {
+        synchronized(controller.mLock) {
+            WeakReference<PendingIntentRecord> current = controller.mIntentSenderRecords.get(key);
             if (current == ref) {
-                owner.mIntentSenderRecords.remove(key);
+                controller.mIntentSenderRecords.remove(key);
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/PersistentConnection.java b/services/core/java/com/android/server/am/PersistentConnection.java
index c5edb26..3490b1d 100644
--- a/services/core/java/com/android/server/am/PersistentConnection.java
+++ b/services/core/java/com/android/server/am/PersistentConnection.java
@@ -24,7 +24,7 @@
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.util.Slog;
+import android.util.Log;
 import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
@@ -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;
 
@@ -100,6 +103,18 @@
     @GuardedBy("mLock")
     private T mService;
 
+    @GuardedBy("mLock")
+    private int mNumConnected;
+
+    @GuardedBy("mLock")
+    private int mNumDisconnected;
+
+    @GuardedBy("mLock")
+    private int mNumBindingDied;
+
+    @GuardedBy("mLock")
+    private long mLastConnectedTime;
+
     private final ServiceConnection mServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
@@ -108,25 +123,35 @@
                     // Callback came in after PersistentConnection.unbind() was called.
                     // We just ignore this.
                     // (We've already called unbindService() already in unbind)
-                    Slog.w(mTag, "Connected: " + mComponentName.flattenToShortString()
+                    Log.w(mTag, "Connected: " + mComponentName.flattenToShortString()
                             + " u" + mUserId + " but not bound, ignore.");
                     return;
                 }
-                Slog.i(mTag, "Connected: " + mComponentName.flattenToShortString()
+                Log.i(mTag, "Connected: " + mComponentName.flattenToShortString()
                         + " u" + mUserId);
 
+                mNumConnected++;
+
                 mIsConnected = true;
+                mLastConnectedTime = injectUptimeMillis();
                 mService = asInterface(service);
+
+                scheduleStableCheckLocked();
             }
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
             synchronized (mLock) {
-                Slog.i(mTag, "Disconnected: " + mComponentName.flattenToShortString()
+                Log.i(mTag, "Disconnected: " + mComponentName.flattenToShortString()
                         + " u" + mUserId);
 
+                mNumDisconnected++;
+
                 cleanUpConnectionLocked();
+
+                // Note we won't increase the rebind timeout here, because we don't explicitly
+                // rebind in this case.
             }
         }
 
@@ -136,13 +161,16 @@
             synchronized (mLock) {
                 if (!mBound) {
                     // Callback came in late?
-                    Slog.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
+                    Log.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
                             + " u" + mUserId + " but not bound, ignore.");
                     return;
                 }
 
-                Slog.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
+                Log.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
                         + " u" + mUserId);
+
+                mNumBindingDied++;
+
                 scheduleRebindLocked();
             }
         }
@@ -152,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;
@@ -162,6 +191,7 @@
         mRebindBackoffMs = rebindBackoffSeconds * 1000;
         mRebindBackoffIncrease = rebindBackoffIncrease;
         mRebindMaxBackoffMs = rebindMaxBackoffSeconds * 1000;
+        mResetBackoffDelay = resetBackoffDelay * 1000;
 
         mNextBackoffMs = mRebindBackoffMs;
     }
@@ -170,6 +200,12 @@
         return mComponentName;
     }
 
+    public final int getUserId() {
+        return mUserId;
+    }
+
+    protected abstract int getBindFlags();
+
     /**
      * @return whether {@link #bind()} has been called and {@link #unbind()} hasn't.
      *
@@ -220,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();
@@ -229,23 +301,24 @@
         }
         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);
 
         if (DEBUG) {
-            Slog.d(mTag, "Attempting to connect to " + mComponentName);
+            Log.d(mTag, "Attempting to connect to " + mComponentName);
         }
 
         final boolean success = mContext.bindServiceAsUser(service, mServiceConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                Context.BIND_AUTO_CREATE | getBindFlags(),
                 mHandler, UserHandle.of(mUserId));
 
         if (!success) {
-            Slog.e(mTag, "Binding: " + service.getComponent() + " u" + mUserId
+            Log.e(mTag, "Binding: " + service.getComponent() + " u" + mUserId
                     + " failed.");
         }
     }
@@ -265,6 +338,8 @@
     private void cleanUpConnectionLocked() {
         mIsConnected = false;
         mService = null;
+
+        unscheduleStableCheckLocked();
     }
 
     /**
@@ -275,6 +350,7 @@
             mShouldBeBound = false;
 
             unbindLocked();
+            unscheduleStableCheckLocked();
         }
     }
 
@@ -285,7 +361,7 @@
         if (!mBound) {
             return;
         }
-        Slog.i(mTag, "Stopping: " + mComponentName.flattenToShortString() + " u" + mUserId);
+        Log.i(mTag, "Stopping: " + mComponentName.flattenToShortString() + " u" + mUserId);
         mBound = false;
         mContext.unbindService(mServiceConnection);
 
@@ -303,7 +379,7 @@
         unbindLocked();
 
         if (!mRebindScheduled) {
-            Slog.i(mTag, "Scheduling to reconnect in " + mNextBackoffMs + " ms (uptime)");
+            Log.i(mTag, "Scheduling to reconnect in " + mNextBackoffMs + " ms (uptime)");
 
             mReconnectTime = injectUptimeMillis() + mNextBackoffMs;
 
@@ -316,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);
 
@@ -323,10 +426,12 @@
         synchronized (mLock) {
             pw.print(prefix);
             pw.print(mComponentName.flattenToShortString());
-            pw.print(mBound ? "  [bound]" : "  [not bound]");
-            pw.print(mIsConnected ? "  [connected]" : "  [not connected]");
+            pw.print(" u");
+            pw.print(mUserId);
+            pw.print(mBound ? " [bound]" : " [not bound]");
+            pw.print(mIsConnected ? " [connected]" : " [not connected]");
             if (mRebindScheduled) {
-                pw.print("  reconnect in ");
+                pw.print(" reconnect in ");
                 TimeUtils.formatDuration((mReconnectTime - injectUptimeMillis()), pw);
             }
             pw.println();
@@ -334,6 +439,20 @@
             pw.print(prefix);
             pw.print("  Next backoff(sec): ");
             pw.print(mNextBackoffMs / 1000);
+            pw.println();
+
+            pw.print(prefix);
+            pw.print("  Connected: ");
+            pw.print(mNumConnected);
+            pw.print("  Disconnected: ");
+            pw.print(mNumDisconnected);
+            pw.print("  Died: ");
+            pw.print(mNumBindingDied);
+            if (mIsConnected) {
+                pw.print("  Duration: ");
+                TimeUtils.formatDuration((injectUptimeMillis() - mLastConnectedTime), pw);
+            }
+            pw.println();
         }
     }
 
@@ -373,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/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index d3dc0f3..667d3fa 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -17,18 +17,10 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
-import android.os.Debug;
-import android.util.ArraySet;
-import android.util.DebugUtils;
-import android.util.EventLog;
-import android.util.Slog;
-import com.android.internal.app.procstats.ProcessStats;
-import com.android.internal.app.procstats.ProcessState;
-import com.android.internal.os.BatteryStatsImpl;
-
 import android.app.ActivityManager;
 import android.app.Dialog;
 import android.app.IApplicationThread;
@@ -36,7 +28,9 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
 import android.os.Binder;
+import android.os.Debug;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
@@ -44,10 +38,18 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.DebugUtils;
+import android.util.EventLog;
+import android.util.Slog;
 import android.util.StatsLog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.app.procstats.ProcessState;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.os.BatteryStatsImpl;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -307,6 +309,7 @@
             pw.print(prefix); pw.print("manageSpaceActivityName=");
             pw.println(info.manageSpaceActivityName);
         }
+
         pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
                 pw.print(" publicDir="); pw.print(info.publicSourceDir);
                 pw.print(" data="); pw.println(info.dataDir);
@@ -520,7 +523,7 @@
     }
 
     ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
-            int _uid) {
+            int _uid, Configuration config) {
         mService = _service;
         info = _info;
         isolated = _info.uid != _uid;
@@ -534,7 +537,7 @@
         removed = false;
         lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
         mWindowProcessController = new WindowProcessController(
-                mService.mActivityTaskManager, info, processName, uid, userId, this, this);
+                mService.mActivityTaskManager, info, processName, uid, userId, this, this, config);
         pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
     }
 
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 8ce650c..6ffd8a9 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -23,8 +23,10 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.service.procstats.ProcessStatsServiceDumpProto;
+import android.text.format.DateFormat;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
+import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -47,6 +49,7 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.locks.ReentrantLock;
@@ -482,6 +485,23 @@
         return finalRes;
     }
 
+    static int parseSectionOptions(String optionsStr) {
+        final String sep = ",";
+        String[] sectionsStr = optionsStr.split(sep);
+        if (sectionsStr.length == 0) {
+            return ProcessStats.REPORT_ALL;
+        }
+        int res = 0;
+        List<String> optionStrList = Arrays.asList(ProcessStats.OPTIONS_STR);
+        for (String sectionStr : sectionsStr) {
+            int optionIndex = optionStrList.indexOf(sectionStr);
+            if (optionIndex != -1) {
+                res |= ProcessStats.OPTIONS[optionIndex];
+            }
+        }
+        return res;
+    }
+
     public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
         mAm.mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.PACKAGE_USAGE_STATS, null);
@@ -514,6 +534,95 @@
         return current.marshall();
     }
 
+    /**
+     * Get stats committed after highWaterMarkMs
+     * @param highWaterMarkMs Report stats committed after this time.
+     * @param section Integer mask to indicage which sections to include in the stats.
+     * @param doAggregate Whether to aggregate the stats or keep them separated.
+     * @return List of proto binary of individual commit files or one that is merged from them.
+     */
+    @Override
+    public long getCommittedStats(long highWaterMarkMs, int section, boolean doAggregate,
+            List<ParcelFileDescriptor> committedStats) {
+        mAm.mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.PACKAGE_USAGE_STATS, null);
+
+        ProcessStats mergedStats = new ProcessStats(false);
+        long newHighWaterMark = highWaterMarkMs;
+        mWriteLock.lock();
+        try {
+            ArrayList<String> files = getCommittedFiles(0, false, true);
+            if (files != null) {
+                String highWaterMarkStr =
+                        DateFormat.format("yyyy-MM-dd-HH-mm-ss", highWaterMarkMs).toString();
+                ProcessStats stats = new ProcessStats(false);
+                for (int i = files.size() - 1; i >= 0; i--) {
+                    String fileName = files.get(i);
+                    try {
+                        String startTimeStr = fileName.substring(
+                                fileName.lastIndexOf(STATE_FILE_PREFIX)
+                                        + STATE_FILE_PREFIX.length(),
+                                fileName.lastIndexOf(STATE_FILE_SUFFIX));
+                        if (startTimeStr.compareToIgnoreCase(highWaterMarkStr) > 0) {
+                            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
+                                    new File(fileName),
+                                    ParcelFileDescriptor.MODE_READ_ONLY);
+                            InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+                            stats.reset();
+                            stats.read(is);
+                            is.close();
+                            if (stats.mTimePeriodStartClock > newHighWaterMark) {
+                                newHighWaterMark = stats.mTimePeriodStartClock;
+                            }
+                            if (doAggregate) {
+                                mergedStats.add(stats);
+                            } else {
+                                committedStats.add(protoToParcelFileDescriptor(stats, section));
+                            }
+                            if (stats.mReadError != null) {
+                                Log.w(TAG, "Failure reading process stats: " + stats.mReadError);
+                                continue;
+                            }
+                        }
+                    } catch (IOException e) {
+                        Slog.w(TAG, "Failure opening procstat file " + fileName, e);
+                    } catch (IndexOutOfBoundsException e) {
+                        Slog.w(TAG, "Failure to read and parse commit file " + fileName, e);
+                    }
+                }
+                if (doAggregate) {
+                    committedStats.add(protoToParcelFileDescriptor(mergedStats, section));
+                }
+                return newHighWaterMark;
+            }
+        } catch (IOException e) {
+            Slog.w(TAG, "Failure opening procstat file", e);
+        } finally {
+            mWriteLock.unlock();
+        }
+        return newHighWaterMark;
+    }
+
+    private ParcelFileDescriptor protoToParcelFileDescriptor(ProcessStats stats, int section)
+            throws IOException {
+        final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
+        Thread thr = new Thread("ProcessStats pipe output") {
+            public void run() {
+                try {
+                    FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]);
+                    final ProtoOutputStream proto = new ProtoOutputStream(fout);
+                    stats.writeToProto(proto, stats.mTimePeriodEndRealtime, section);
+                    proto.flush();
+                    fout.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failure writing pipe", e);
+                }
+            }
+        };
+        thr.start();
+        return fds[0];
+    }
+
     public ParcelFileDescriptor getStatsOverTime(long minTime) {
         mAm.mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.PACKAGE_USAGE_STATS, null);
@@ -594,7 +703,7 @@
 
     private void dumpAggregatedStats(PrintWriter pw, long aggregateHours, long now,
             String reqPackage, boolean isCompact, boolean dumpDetails, boolean dumpFullDetails,
-            boolean dumpAll, boolean activeOnly) {
+            boolean dumpAll, boolean activeOnly, int section) {
         ParcelFileDescriptor pfd = getStatsOverTime(aggregateHours*60*60*1000
                 - (ProcessStats.COMMIT_PERIOD/2));
         if (pfd == null) {
@@ -609,11 +718,11 @@
             return;
         }
         if (isCompact) {
-            stats.dumpCheckinLocked(pw, reqPackage);
+            stats.dumpCheckinLocked(pw, reqPackage, section);
         } else {
             if (dumpDetails || dumpFullDetails) {
                 stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll,
-                        activeOnly);
+                        activeOnly, section);
             } else {
                 stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
             }
@@ -643,6 +752,8 @@
         pw.println("  --max: for -a, max num of historical batches to print.");
         pw.println("  --active: only show currently active processes/services.");
         pw.println("  --commit: commit current stats to disk and reset to start new stats.");
+        pw.println("  --section: proc|pkg-proc|pkg-svc|pkg-asc|pkg-all|all ");
+        pw.println("    options can be combined to select desired stats");
         pw.println("  --reset: reset current stats, without committing.");
         pw.println("  --clear: clear all stats; does both --reset and deletes old stats.");
         pw.println("  --write: write current in-memory stats to disk.");
@@ -696,6 +807,7 @@
         int[] csvMemStats = new int[] { ProcessStats.ADJ_MEM_FACTOR_CRITICAL};
         boolean csvSepProcStats = true;
         int[] csvProcStats = ProcessStats.ALL_PROC_STATES;
+        int section = ProcessStats.REPORT_ALL;
         if (args != null) {
             for (int i=0; i<args.length; i++) {
                 String arg = args[i];
@@ -814,13 +926,14 @@
                         pw.println("Process stats committed.");
                         quit = true;
                     }
-                } else if ("--reset".equals(arg)) {
-                    synchronized (mAm) {
-                        mProcessStats.resetSafely();
-                        mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
-                        pw.println("Process stats reset.");
-                        quit = true;
+                } else if ("--section".equals(arg)) {
+                    i++;
+                    if (i >= args.length) {
+                        pw.println("Error: argument required for --section");
+                        dumpHelp(pw);
+                        return;
                     }
+                    section = parseSectionOptions(args[i]);
                 } else if ("--clear".equals(arg)) {
                     synchronized (mAm) {
                         mProcessStats.resetSafely();
@@ -946,7 +1059,7 @@
         } else if (aggregateHours != 0) {
             pw.print("AGGREGATED OVER LAST "); pw.print(aggregateHours); pw.println(" HOURS:");
             dumpAggregatedStats(pw, aggregateHours, now, reqPackage, isCompact,
-                    dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+                    dumpDetails, dumpFullDetails, dumpAll, activeOnly, section);
             return;
         } else if (lastIndex > 0) {
             pw.print("LAST STATS AT INDEX "); pw.print(lastIndex); pw.println(":");
@@ -968,7 +1081,7 @@
             boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
             if (isCheckin || isCompact) {
                 // Don't really need to lock because we uniquely own this object.
-                processStats.dumpCheckinLocked(pw, reqPackage);
+                processStats.dumpCheckinLocked(pw, reqPackage, section);
             } else {
                 pw.print("COMMITTED STATS FROM ");
                 pw.print(processStats.mTimePeriodStartClockStr);
@@ -976,7 +1089,7 @@
                 pw.println(":");
                 if (dumpDetails || dumpFullDetails) {
                     processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
-                            dumpAll, activeOnly);
+                            dumpAll, activeOnly, section);
                     if (dumpAll) {
                         pw.print("  mFile="); pw.println(mFile.getBaseFile());
                     }
@@ -1015,7 +1128,7 @@
                             boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
                             if (isCheckin || isCompact) {
                                 // Don't really need to lock because we uniquely own this object.
-                                processStats.dumpCheckinLocked(pw, reqPackage);
+                                processStats.dumpCheckinLocked(pw, reqPackage, section);
                             } else {
                                 if (sepNeeded) {
                                     pw.println();
@@ -1031,7 +1144,7 @@
                                 // much crud.
                                 if (dumpFullDetails) {
                                     processStats.dumpLocked(pw, reqPackage, now, false, false,
-                                            false, activeOnly);
+                                            false, activeOnly, section);
                                 } else {
                                     processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
                                 }
@@ -1054,7 +1167,7 @@
         if (!isCheckin) {
             synchronized (mAm) {
                 if (isCompact) {
-                    mProcessStats.dumpCheckinLocked(pw, reqPackage);
+                    mProcessStats.dumpCheckinLocked(pw, reqPackage, section);
                 } else {
                     if (sepNeeded) {
                         pw.println();
@@ -1062,7 +1175,7 @@
                     pw.println("CURRENT STATS:");
                     if (dumpDetails || dumpFullDetails) {
                         mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
-                                dumpAll, activeOnly);
+                                dumpAll, activeOnly, section);
                         if (dumpAll) {
                             pw.print("  mFile="); pw.println(mFile.getBaseFile());
                         }
@@ -1078,11 +1191,11 @@
                 }
                 pw.println("AGGREGATED OVER LAST 24 HOURS:");
                 dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
-                        dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+                        dumpDetails, dumpFullDetails, dumpAll, activeOnly, section);
                 pw.println();
                 pw.println("AGGREGATED OVER LAST 3 HOURS:");
                 dumpAggregatedStats(pw, 3, now, reqPackage, isCompact,
-                        dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+                        dumpDetails, dumpFullDetails, dumpAll, activeOnly, section);
             }
         }
     }
@@ -1099,7 +1212,9 @@
         if (stats.mReadError != null) {
             return;
         }
-        stats.writeToProto(proto, fieldId, now);
+        final long token = proto.start(fieldId);
+        stats.writeToProto(proto, now, ProcessStats.REPORT_ALL);
+        proto.end(token);
     }
 
     private void dumpProto(FileDescriptor fd) {
@@ -1109,7 +1224,9 @@
         long now;
         synchronized (mAm) {
             now = SystemClock.uptimeMillis();
-            mProcessStats.writeToProto(proto,ProcessStatsServiceDumpProto.PROCSTATS_NOW, now);
+            final long token = proto.start(ProcessStatsServiceDumpProto.PROCSTATS_NOW);
+            mProcessStats.writeToProto(proto, now, ProcessStats.REPORT_ALL);
+            proto.end(token);
         }
 
         // aggregated over last 3 hours procstats
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index e11e003..dd13e98 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -30,8 +30,9 @@
 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 android.view.Display.DEFAULT_DISPLAY;
+
 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;
@@ -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;
@@ -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 f7de7f4..fa0cb47 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -44,7 +44,7 @@
  * the inner options. Also supports having two set of options: Once from the original caller, and
  * once from the caller that is overriding it, which happens when sending a {@link PendingIntent}.
  */
-class SafeActivityOptions {
+public class SafeActivityOptions {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "SafeActivityOptions" : TAG_AM;
 
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 7256e23..05b0d59 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -45,7 +45,6 @@
 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;
@@ -75,7 +74,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;
@@ -129,7 +127,8 @@
 import java.util.ArrayList;
 import java.util.Objects;
 
-class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
+// 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_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
@@ -1521,14 +1520,14 @@
 
     /**
      * Check whether this task can be launched on the specified display.
+     *
      * @param displayId Target display id.
-     * @return {@code true} if either it is the default display or this activity is resizeable and
-     *         can be put a secondary screen.
+     * @return {@code true} if either it is the default display or this activity can be put on a
+     *         secondary display.
      */
     boolean canBeLaunchedOnDisplay(int displayId) {
         return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
-                isResizeable(false /* checkSupportsPip */), -1 /* don't check PID */,
-                -1 /* don't check UID */, null /* activityInfo */);
+                -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
     }
 
     /**
@@ -1685,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/UserController.java b/services/core/java/com/android/server/am/UserController.java
index bd412fc..3a897c4 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -850,10 +850,16 @@
     }
 
     void scheduleStartProfiles() {
-        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
-            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
-                    DateUtils.SECOND_IN_MILLIS);
-        }
+        // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
+        // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
+        // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
+        // after the parent had chance to unlock fully.
+        FgThread.getHandler().post(() -> {
+            if (!mHandler.hasMessages(START_PROFILES_MSG)) {
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
+                        DateUtils.SECOND_IN_MILLIS);
+            }
+        });
     }
 
     void startProfiles() {
@@ -2172,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) {
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index e5551b5..f6f4db6 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -17,7 +17,10 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+
+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;
@@ -29,11 +32,13 @@
 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
 
 import android.app.Activity;
-import android.app.ActivityTaskManager;
 import android.app.ActivityThread;
 import android.app.IApplicationThread;
+import android.app.servertransaction.ConfigurationChangeItem;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
+import android.os.Message;
 import android.os.RemoteException;
 import android.util.ArraySet;
 import android.util.Log;
@@ -41,7 +46,7 @@
 
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.internal.util.function.pooled.PooledRunnable;
+import com.android.server.wm.ConfigurationContainer;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -57,9 +62,10 @@
  * window manager so the window manager lock is held and appropriate permissions are checked before
  * calls are allowed to proceed.
  */
-public class WindowProcessController {
+public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer> {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_AM;
     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
+    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
     // all about the first app in the process
     final ApplicationInfo mInfo;
@@ -108,8 +114,12 @@
     // any tasks this process had run root activities in
     private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>();
 
+    // Last configuration that was reported to the process.
+    private final Configuration mLastReportedConfiguration;
+
     WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, String name,
-            int uid, int userId, Object owner, WindowProcessListener listener) {
+            int uid, int userId, Object owner, WindowProcessListener listener,
+            Configuration config) {
         mInfo = info;
         mName = name;
         mUid = uid;
@@ -117,6 +127,10 @@
         mOwner = owner;
         mListener = listener;
         mAtm = atm;
+        mLastReportedConfiguration = new Configuration();
+        if (config != null) {
+            onConfigurationChanged(config);
+        }
     }
 
     public void setPid(int pid) {
@@ -219,6 +233,21 @@
         return mInstrumenting;
     }
 
+    @Override
+    protected int getChildCount() {
+        return 0;
+    }
+
+    @Override
+    protected ConfigurationContainer getChildAt(int index) {
+        return null;
+    }
+
+    @Override
+    protected ConfigurationContainer getParent() {
+        return null;
+    }
+
     public void addPackage(String packageName) {
         synchronized (mAtm.mGlobalLock) {
             mPkgList.add(packageName);
@@ -482,48 +511,94 @@
     void clearProfilerIfNeeded() {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
-        mAtm.mH.post(() -> mListener.clearProfilerIfNeeded());
+        mAtm.mH.sendMessage(PooledLambda.obtainMessage(
+                WindowProcessListener::clearProfilerIfNeeded, mListener));
     }
 
     void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
             boolean activityChange, boolean updateOomAdj) {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
-        final Runnable r = PooledLambda.obtainRunnable(WindowProcessListener::updateProcessInfo,
+        final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
                 mListener, updateServiceConnectionActivities, updateLru, activityChange,
                 updateOomAdj);
-        mAtm.mH.post(r);
+        mAtm.mH.sendMessage(m);
     }
 
     void updateServiceConnectionActivities() {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
-        mAtm.mH.post(() -> mListener.updateServiceConnectionActivities());
+        mAtm.mH.sendMessage(PooledLambda.obtainMessage(
+                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 Runnable r = PooledLambda.obtainRunnable(
+        final Message m = PooledLambda.obtainMessage(
                 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
-        mAtm.mH.post(r);
+        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.
-        final Runnable r = PooledLambda.obtainRunnable(
+        final Message m = PooledLambda.obtainMessage(
                 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
                 mListener, newState);
-        mAtm.mH.post(r);
+        mAtm.mH.sendMessage(m);
     }
 
     void setRemoved(boolean removed) {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
-        final Runnable r = PooledLambda.obtainRunnable(
+        final Message m = PooledLambda.obtainMessage(
                 WindowProcessListener::setRemoved, mListener, removed);
-        mAtm.mH.post(r);
+        mAtm.mH.sendMessage(m);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newGlobalConfig) {
+        super.onConfigurationChanged(newGlobalConfig);
+        updateConfiguration();
+    }
+
+    @Override
+    public void onOverrideConfigurationChanged(Configuration newOverrideConfig) {
+        super.onOverrideConfigurationChanged(newOverrideConfig);
+        updateConfiguration();
+    }
+
+    private void updateConfiguration() {
+        final Configuration config = getConfiguration();
+        if (mLastReportedConfiguration.diff(config) == 0) {
+            // Nothing changed.
+            return;
+        }
+
+        try {
+            if (mThread == null) {
+                return;
+            }
+            if (DEBUG_CONFIGURATION) {
+                Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName
+                        + " new config " + config);
+            }
+            config.seq = mAtm.increaseConfigurationSeqLocked();
+            mAtm.getLifecycleManager().scheduleTransaction(mThread,
+                    ConfigurationChangeItem.obtain(config));
+            setLastReportedConfiguration(config);
+        } catch (Exception e) {
+            Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
+        }
+    }
+
+    private void setLastReportedConfiguration(Configuration config) {
+        mLastReportedConfiguration.setTo(config);
+    }
+
+    Configuration getLastReportedConfiguration() {
+        return mLastReportedConfiguration;
     }
 
     /** Returns the total time (in milliseconds) spent executing in both user and system code. */
@@ -574,6 +649,9 @@
                 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
             }
         }
+        pw.println(prefix + " Configuration=" + getConfiguration());
+        pw.println(prefix + " OverrideConfiguration=" + getOverrideConfiguration());
+        pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
     }
 
 }
diff --git a/services/core/java/com/android/server/appbinding/AppBindingConstants.java b/services/core/java/com/android/server/appbinding/AppBindingConstants.java
new file mode 100644
index 0000000..7184769
--- /dev/null
+++ b/services/core/java/com/android/server/appbinding/AppBindingConstants.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.appbinding;
+
+import android.content.Context;
+import android.util.KeyValueListParser;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Constants that are configurable via the global settings for {@link AppBindingService}.
+ */
+public class AppBindingConstants {
+    private static final String TAG = AppBindingService.TAG;
+
+    private static final String SERVICE_RECONNECT_BACKOFF_SEC_KEY =
+            "service_reconnect_backoff_sec";
+
+    private static final String SERVICE_RECONNECT_BACKOFF_INCREASE_KEY =
+            "service_reconnect_backoff_increase";
+
+    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;
+
+    /**
+     * The back-off before re-connecting, when a service binding died, due to the app
+     * crashing repeatedly.
+     */
+    public final long SERVICE_RECONNECT_BACKOFF_SEC;
+
+    /**
+     * The exponential back-off increase factor when a binding dies multiple times.
+     */
+    public final double SERVICE_RECONNECT_BACKOFF_INCREASE;
+
+    /**
+     * The max back-off
+     */
+    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;
+
+        final KeyValueListParser parser = new KeyValueListParser(',');
+        try {
+            parser.setString(settings);
+        } catch (IllegalArgumentException e) {
+            // Failed to parse the settings string, log this and move on
+            // with defaults.
+            Slog.e(TAG, "Bad setting: " + settings);
+        }
+
+        long serviceReconnectBackoffSec = parser.getLong(
+                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.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);
+
+        // Set minimum: 1.0.
+        serviceReconnectBackoffIncrease =
+                Math.max(1, serviceReconnectBackoffIncrease);
+
+        // Make sure max >= default back off.
+        serviceReconnectMaxBackoffSec = Math.max(serviceReconnectBackoffSec,
+                serviceReconnectMaxBackoffSec);
+
+        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;
+    }
+
+    /**
+     * Create a new instance from a settings string.
+     */
+    public static AppBindingConstants initializeFromString(String settings) {
+        return new AppBindingConstants(settings);
+    }
+
+    /**
+     * dumpsys support.
+     */
+    public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix);
+        pw.print("Constants: ");
+        pw.println(sourceSettings);
+
+        pw.print(prefix);
+        pw.print("  SERVICE_RECONNECT_BACKOFF_SEC: ");
+        pw.println(SERVICE_RECONNECT_BACKOFF_SEC);
+
+        pw.print(prefix);
+        pw.print("  SERVICE_RECONNECT_BACKOFF_INCREASE: ");
+        pw.println(SERVICE_RECONNECT_BACKOFF_INCREASE);
+
+        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
new file mode 100644
index 0000000..3131255
--- /dev/null
+++ b/services/core/java/com/android/server/appbinding/AppBindingService.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.appbinding;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+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;
+import android.content.pm.IPackageManager;
+import android.content.pm.ServiceInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
+import com.android.server.SystemService;
+import com.android.server.am.PersistentConnection;
+import com.android.server.appbinding.finders.AppServiceFinder;
+import com.android.server.appbinding.finders.SmsAppServiceFinder;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * System server that keeps a binding to an app to keep it always running.
+ *
+ * <p>As of android Q, we only use it for the default SMS app.
+ *
+ * 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";
+
+    public static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
+
+    private final Object mLock = new Object();
+
+    private final Injector mInjector;
+    private final Context mContext;
+    private final Handler mHandler;
+    private final IPackageManager mIPackageManager;
+
+    @GuardedBy("mLock")
+    private AppBindingConstants mConstants;
+
+    @GuardedBy("mLock")
+    private final SparseBooleanArray mRunningUsers = new SparseBooleanArray(2);
+
+    @GuardedBy("mLock")
+    private final ArrayList<AppServiceFinder> mApps = new ArrayList<>();
+
+    @GuardedBy("mLock")
+    private final ArrayList<AppServiceConnection> mConnections = new ArrayList<>();
+
+    static class Injector {
+        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 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(injector, context);
+        }
+
+        @Override
+        public void onStart() {
+            publishBinderService(Context.APP_BINDING_SERVICE, mService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            mService.onBootPhase(phase);
+        }
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userId) {
+            mService.onUnlockUser(userId);
+        }
+
+        @Override
+        public void onStopUser(int userHandle) {
+            mService.onStopUser(userHandle);
+        }
+    }
+
+    private AppBindingService(Injector injector, Context context) {
+        mInjector = injector;
+        mContext = context;
+
+        mIPackageManager = injector.getIPackageManager();
+
+        mHandler = BackgroundThread.getHandler();
+        mApps.add(new SmsAppServiceFinder(context, this::onAppChanged, mHandler));
+
+        // Initialize with the default value to make it non-null.
+        mConstants = AppBindingConstants.initializeFromString("");
+    }
+
+    private void forAllAppsLocked(Consumer<AppServiceFinder> consumer) {
+        for (int i = 0; i < mApps.size(); i++) {
+            consumer.accept(mApps.get(i));
+        }
+    }
+
+    private void onBootPhase(int phase) {
+        if (DEBUG) {
+            Slog.d(TAG, "onBootPhase: " + phase);
+        }
+        switch (phase) {
+            case SystemService.PHASE_ACTIVITY_MANAGER_READY:
+                onPhaseActivityManagerReady();
+                break;
+            case SystemService.PHASE_THIRD_PARTY_APPS_CAN_START:
+                onPhaseThirdPartyAppsCanStart();
+                break;
+        }
+    }
+
+    /**
+     * Handle boot phase PHASE_ACTIVITY_MANAGER_READY.
+     */
+    private void onPhaseActivityManagerReady() {
+        final IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        packageFilter.addDataScheme("package");
+
+        packageFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        mContext.registerReceiverAsUser(mPackageUserMonitor, UserHandle.ALL,
+                packageFilter, null, mHandler);
+
+        final IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(Intent.ACTION_USER_REMOVED);
+        mContext.registerReceiverAsUser(mPackageUserMonitor, UserHandle.ALL,
+                userFilter, null, mHandler);
+
+        mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.APP_BINDING_CONSTANTS), false, mSettingsObserver);
+
+        refreshConstants();
+    }
+
+    private final ContentObserver mSettingsObserver = new ContentObserver(null) {
+        @Override
+        public void onChange(boolean selfChange) {
+            refreshConstants();
+        }
+    };
+
+    private void refreshConstants() {
+        final String newSetting = mInjector.getGlobalSettingString(
+                mContext.getContentResolver(), Global.APP_BINDING_CONSTANTS);
+
+        synchronized (mLock) {
+            if (TextUtils.equals(mConstants.sourceSettings, newSetting)) {
+                return;
+            }
+            Slog.i(TAG, "Updating constants with: " + newSetting);
+            mConstants = AppBindingConstants.initializeFromString(newSetting);
+
+            rebindAllLocked("settings update");
+        }
+    }
+
+    @VisibleForTesting
+    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);
+                return;
+            }
+
+            final String action = intent.getAction();
+
+            if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                onUserRemoved(userId);
+                return;
+            }
+
+            final Uri intentUri = intent.getData();
+            final String packageName = (intentUri != null) ? intentUri.getSchemeSpecificPart()
+                    : null;
+            if (packageName == null) {
+                Slog.w(TAG, "Intent broadcast does not contain package name: " + intent);
+                return;
+            }
+
+            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+            switch (action) {
+                case Intent.ACTION_PACKAGE_ADDED:
+                    if (replacing) {
+                        handlePackageAddedReplacing(packageName, userId);
+                    }
+                    break;
+                case Intent.ACTION_PACKAGE_REMOVED:
+                    if (!replacing) {
+                        handlePackageRemoved(packageName, userId);
+                    }
+                    break;
+                case Intent.ACTION_PACKAGE_CHANGED:
+                    handlePackageChanged(packageName, userId);
+                    break;
+            }
+        }
+    };
+
+    /**
+     * Handle boot phase PHASE_THIRD_PARTY_APPS_CAN_START.
+     */
+    private void onPhaseThirdPartyAppsCanStart() {
+        synchronized (mLock) {
+            forAllAppsLocked(AppServiceFinder::startMonitoring);
+        }
+    }
+
+    /** User lifecycle callback. */
+    private void onStartUser(int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onStartUser: u" + userId);
+        }
+        synchronized (mLock) {
+            mRunningUsers.append(userId, true);
+            bindServicesLocked(userId, null, "user start");
+        }
+    }
+
+    /** User lifecycle callback. */
+    private void onUnlockUser(int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onUnlockUser: u" + userId);
+        }
+        synchronized (mLock) {
+            bindServicesLocked(userId, null, "user unlock");
+        }
+    }
+
+    /** User lifecycle callback. */
+    private void onStopUser(int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onStopUser: u" + userId);
+        }
+        synchronized (mLock) {
+            unbindServicesLocked(userId, null, "user stop");
+
+            mRunningUsers.delete(userId);
+        }
+    }
+
+    private void onUserRemoved(int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onUserRemoved: u" + userId);
+        }
+        synchronized (mLock) {
+            forAllAppsLocked((app) -> app.onUserRemoved(userId));
+
+            mRunningUsers.delete(userId);
+        }
+    }
+
+    /**
+     * Called when a target package changes; e.g. when the user changes the default SMS app.
+     */
+    private void onAppChanged(AppServiceFinder finder, int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onAppChanged: u" + userId + " " + finder.getAppDescription());
+        }
+        synchronized (mLock) {
+            final String reason = finder.getAppDescription() + " changed";
+            unbindServicesLocked(userId, finder, reason);
+            bindServicesLocked(userId, finder, reason);
+        }
+    }
+
+    @Nullable
+    private AppServiceFinder findFinderLocked(int userId, @NonNull String packageName) {
+        for (int i = 0; i < mApps.size(); i++) {
+            final AppServiceFinder app = mApps.get(i);
+            if (packageName.equals(app.getTargetPackage(userId))) {
+                return app;
+            }
+        }
+        return null;
+    }
+
+    @Nullable
+    private AppServiceConnection findConnectionLock(
+            int userId, @NonNull AppServiceFinder target) {
+        for (int i = 0; i < mConnections.size(); i++) {
+            final AppServiceConnection conn = mConnections.get(i);
+            if ((conn.getUserId() == userId) && (conn.getFinder() == target)) {
+                return conn;
+            }
+        }
+        return null;
+    }
+
+    private void handlePackageAddedReplacing(String packageName, int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "handlePackageAddedReplacing: u" + userId + " " + packageName);
+        }
+        synchronized (mLock) {
+            final AppServiceFinder finder = findFinderLocked(userId, packageName);
+            if (finder != null) {
+                unbindServicesLocked(userId, finder, "package update");
+                bindServicesLocked(userId, finder, "package update");
+            }
+        }
+    }
+
+    private void handlePackageRemoved(String packageName, int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "handlePackageRemoved: u" + userId + " " + packageName);
+        }
+        synchronized (mLock) {
+            final AppServiceFinder finder = findFinderLocked(userId, packageName);
+            if (finder != null) {
+                unbindServicesLocked(userId, finder, "package uninstall");
+            }
+        }
+    }
+
+    private void handlePackageChanged(String packageName, int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "handlePackageChanged: u" + userId + " " + packageName);
+        }
+        synchronized (mLock) {
+            final AppServiceFinder finder = findFinderLocked(userId, packageName);
+            if (finder != null) {
+                unbindServicesLocked(userId, finder, "package changed");
+                bindServicesLocked(userId, finder, "package changed");
+            }
+        }
+    }
+
+    private void rebindAllLocked(String reason) {
+        for (int i = 0; i < mRunningUsers.size(); i++) {
+            if (!mRunningUsers.valueAt(i)) {
+                continue;
+            }
+            final int userId = mRunningUsers.keyAt(i);
+
+            unbindServicesLocked(userId, null, reason);
+            bindServicesLocked(userId, null, reason);
+        }
+    }
+
+    private void bindServicesLocked(int userId, @Nullable AppServiceFinder target,
+            @NonNull String reasonForLog) {
+        for (int i = 0; i < mApps.size(); i++) {
+            final AppServiceFinder app = mApps.get(i);
+            if (target != null && target != app) {
+                continue;
+            }
+
+            // Disconnect from existing binding.
+            final AppServiceConnection existingConn = findConnectionLock(userId, app);
+            if (existingConn != null) {
+                unbindServicesLocked(userId, target, reasonForLog);
+            }
+
+            final ServiceInfo service = app.findService(userId, mIPackageManager, mConstants);
+            if (service == null) {
+                continue;
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "bindServicesLocked: u" + userId + " " + app.getAppDescription()
+                        + " binding " + service.getComponentName() + " for " + reasonForLog);
+            }
+            final AppServiceConnection conn =
+                    new AppServiceConnection(mContext, userId, mConstants, mHandler,
+                            app, service.getComponentName());
+            mConnections.add(conn);
+            conn.bind();
+        }
+    }
+
+    private void unbindServicesLocked(int userId, @Nullable AppServiceFinder target,
+            @NonNull String reasonForLog) {
+        for (int i = mConnections.size() - 1; i >= 0; i--) {
+            final AppServiceConnection conn = mConnections.get(i);
+            if ((conn.getUserId() != userId)
+                    || (target != null && conn.getFinder() != target)) {
+                continue;
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "unbindServicesLocked: u" + userId
+                        + " " + conn.getFinder().getAppDescription()
+                        + " unbinding " + conn.getComponentName() + " for " + reasonForLog);
+            }
+            mConnections.remove(i);
+            conn.unbind();
+        }
+    }
+
+    private static class AppServiceConnection extends PersistentConnection<IInterface> {
+        private final AppBindingConstants mConstants;
+        private final AppServiceFinder mFinder;
+
+        AppServiceConnection(Context context, int userId, AppBindingConstants constants,
+                Handler handler, AppServiceFinder finder,
+                @NonNull ComponentName componentName) {
+            super(TAG, context, handler, userId, componentName,
+                    constants.SERVICE_RECONNECT_BACKOFF_SEC,
+                    constants.SERVICE_RECONNECT_BACKOFF_INCREASE,
+                    constants.SERVICE_RECONNECT_MAX_BACKOFF_SEC,
+                    constants.SERVICE_STABLE_CONNECTION_THRESHOLD_SEC);
+            mFinder = finder;
+            mConstants = constants;
+        }
+
+        @Override
+        protected int getBindFlags() {
+            return mFinder.getBindFlags(mConstants);
+        }
+
+        @Override
+        protected IInterface asInterface(IBinder obj) {
+            return mFinder.asInterface(obj);
+        }
+
+        public AppServiceFinder getFinder() {
+            return mFinder;
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
+        if (args.length > 0 && "-s".equals(args[0])) {
+            dumpSimple(pw);
+            return;
+        }
+
+        synchronized (mLock) {
+            mConstants.dump("  ", pw);
+
+            pw.println();
+            pw.print("  Running users:");
+            for (int i = 0; i < mRunningUsers.size(); i++) {
+                if (mRunningUsers.valueAt(i)) {
+                    pw.print(" ");
+                    pw.print(mRunningUsers.keyAt(i));
+                }
+            }
+
+            pw.println();
+            pw.println("  Connections:");
+            for (int i = 0; i < mConnections.size(); i++) {
+                final AppServiceConnection conn = mConnections.get(i);
+                pw.print("    App type: ");
+                pw.print(conn.getFinder().getAppDescription());
+                pw.println();
+
+                conn.dump("      ", pw);
+            }
+            if (mConnections.size() == 0) {
+                pw.println("    None:");
+            }
+
+            pw.println();
+            pw.println("  Finders:");
+            forAllAppsLocked((app) -> app.dump("    ", pw));
+        }
+    }
+
+    /**
+     * Print simple output for CTS.
+     */
+    private void dumpSimple(PrintWriter pw) {
+        synchronized (mLock) {
+            for (int i = 0; i < mConnections.size(); i++) {
+                final AppServiceConnection conn = mConnections.get(i);
+
+                pw.print("conn,");
+                pw.print(conn.getFinder().getAppDescription());
+                pw.print(",");
+                pw.print(conn.getUserId());
+                pw.print(",");
+                pw.print(conn.getComponentName().getPackageName());
+                pw.print(",");
+                pw.print(conn.getComponentName().getClassName());
+                pw.print(",");
+                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/AppBindingUtils.java b/services/core/java/com/android/server/appbinding/AppBindingUtils.java
new file mode 100644
index 0000000..fcbaecf
--- /dev/null
+++ b/services/core/java/com/android/server/appbinding/AppBindingUtils.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.server.appbinding;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Utility class to find a persistent bound service within an app.
+ */
+public class AppBindingUtils {
+    private static final String TAG = "AppBindingUtils";
+    private AppBindingUtils() {
+    }
+
+    /**
+     * Find a service with the action {@code serviceAction} in the package {@code packageName}.
+     * Returns null in any of the following cases.
+     * - No service with the action is found.
+     * - More than 1 service with the action is found.
+     * - Found service is not protected with the permission {@code servicePermission}.
+     */
+    @Nullable
+    public static ServiceInfo findService(@NonNull String packageName, int userId,
+            String serviceAction, String servicePermission,
+            Class<?> serviceClassForLogging,
+            IPackageManager ipm,
+            StringBuilder errorMessage) {
+        final String simpleClassName = serviceClassForLogging.getSimpleName();
+        final Intent intent = new Intent(serviceAction);
+        intent.setPackage(packageName);
+
+        errorMessage.setLength(0); // Clear it.
+        try {
+            final ParceledListSlice<ResolveInfo> pls = ipm
+                    .queryIntentServices(intent, null, /* flags=*/ 0, userId);
+            if (pls == null || pls.getList().size() == 0) {
+                errorMessage.append("Service with " + serviceAction + " not found.");
+                return null;
+            }
+            final List<ResolveInfo> list = pls.getList();
+            // Note if multiple services are found, that's an error, even if only one of them
+            // is exported.
+            if (list.size() > 1) {
+                errorMessage.append("More than one " + simpleClassName + "'s found in package "
+                                + packageName + ".  They'll all be ignored.");
+                Log.e(TAG, errorMessage.toString());
+                return null;
+            }
+            final ServiceInfo si = list.get(0).serviceInfo;
+
+            if (!servicePermission.equals(si.permission)) {
+                errorMessage.append(simpleClassName + " "
+                        + si.getComponentName().flattenToShortString()
+                        + " must be protected with " + servicePermission
+                        + ".");
+                Log.e(TAG, errorMessage.toString());
+                return null;
+            }
+            return si;
+        } catch (RemoteException e) {
+            // Shouldn't happen
+        }
+        return null;
+    }
+}
diff --git a/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java b/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java
new file mode 100644
index 0000000..a075c50
--- /dev/null
+++ b/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.appbinding.finders;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.ServiceInfo;
+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;
+
+import java.io.PrintWriter;
+import java.util.function.BiConsumer;
+
+/**
+ * Baseclss that finds "persistent" service from a type of an app.
+ *
+ * @param <TServiceType> Type of the target service class.
+ * @param <TServiceInterfaceType> Type of the IInterface class used by TServiceType.
+ */
+public abstract class AppServiceFinder<TServiceType, TServiceInterfaceType extends IInterface> {
+    protected static final String TAG = AppBindingService.TAG;
+    protected static final boolean DEBUG = AppBindingService.DEBUG;
+
+    protected final Context mContext;
+    protected final BiConsumer<AppServiceFinder, Integer> mListener;
+    protected final Handler mHandler;
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final SparseArray<String> mTargetPackages = new SparseArray(4);
+
+    @GuardedBy("mLock")
+    private final SparseArray<ServiceInfo> mTargetServices = new SparseArray(4);
+
+    @GuardedBy("mLock")
+    private final SparseArray<String> mLastMessages = new SparseArray(4);
+
+    public AppServiceFinder(Context context,
+            BiConsumer<AppServiceFinder, Integer> listener,
+            Handler callbackHandler) {
+        mContext = context;
+        mListener = listener;
+        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();
+
+    /** Start monitoring apps. (e.g. Start watching the default SMS app changes.) */
+    public void startMonitoring() {
+    }
+
+    /** Called when a user is removed. */
+    public void onUserRemoved(int userId) {
+        synchronized (mLock) {
+            mTargetPackages.delete(userId);
+            mTargetServices.delete(userId);
+            mLastMessages.delete(userId);
+        }
+    }
+
+    /**
+     * Find the target service from the target app on a given user.
+     */
+    @Nullable
+    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) {
+                Slog.d(TAG, getAppDescription() + " package=" + targetPackage);
+            }
+            if (targetPackage == null) {
+                final String message = "Target package not found";
+                mLastMessages.put(userId, message);
+                Slog.w(TAG, getAppDescription() + " u" + userId + " " + message);
+                return null;
+            }
+            mTargetPackages.put(userId, targetPackage);
+
+            final StringBuilder errorMessage = new StringBuilder();
+            final ServiceInfo service = AppBindingUtils.findService(
+                    targetPackage,
+                    userId,
+                    getServiceAction(),
+                    getServicePermission(),
+                    getServiceClass(),
+                    ipm,
+                    errorMessage);
+
+            if (service == null) {
+                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);
+            mTargetServices.put(userId, service);
+            return service;
+        }
+    }
+
+    protected abstract Class<TServiceType> getServiceClass();
+
+    /**
+     * Convert a binder reference to a service interface type.
+     */
+    public abstract TServiceInterfaceType asInterface(IBinder obj);
+
+    /**
+     * @return the target package on a given user.
+     */
+    @Nullable
+    public abstract String getTargetPackage(int userId);
+
+    /**
+     * @return the intent action that identifies the target service in the target app.
+     */
+    @NonNull
+    protected abstract String getServiceAction();
+
+    /**
+     * @return the permission that the target service must be protected with.
+     */
+    @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);
+        pw.print("App type: ");
+        pw.print(getAppDescription());
+        pw.println();
+
+        synchronized (mLock) {
+            for (int i = 0; i < mTargetPackages.size(); i++) {
+                final int userId = mTargetPackages.keyAt(i);
+                pw.print(prefix);
+                pw.print("  User: ");
+                pw.print(userId);
+                pw.println();
+
+                pw.print(prefix);
+                pw.print("    Package: ");
+                pw.print(mTargetPackages.get(userId));
+                pw.println();
+
+                pw.print(prefix);
+                pw.print("    Service: ");
+                pw.print(mTargetServices.get(userId));
+                pw.println();
+
+                pw.print(prefix);
+                pw.print("    Message: ");
+                pw.print(mLastMessages.get(userId));
+                pw.println();
+            }
+        }
+    }
+
+    /** Dumpys support */
+    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(userId);
+                pw.print(",");
+                pw.print(mTargetPackages.get(userId));
+                pw.print(",");
+                pw.print(mTargetServices.get(userId));
+                pw.print(",");
+                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
new file mode 100644
index 0000000..fcc28f8
--- /dev/null
+++ b/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.appbinding.finders;
+
+import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
+
+import android.Manifest.permission;
+import android.app.ISmsAppService;
+import android.app.SmsAppService;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+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;
+
+/**
+ * Find the SmsAppService service within the default SMS app.
+ */
+public class SmsAppServiceFinder extends AppServiceFinder<SmsAppService, ISmsAppService> {
+    public SmsAppServiceFinder(Context context,
+            BiConsumer<AppServiceFinder, Integer> listener,
+            Handler callbackHandler) {
+        super(context, listener, callbackHandler);
+    }
+
+    @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]";
+    }
+
+    @Override
+    protected Class<SmsAppService> getServiceClass() {
+        return SmsAppService.class;
+    }
+
+    @Override
+    public ISmsAppService asInterface(IBinder obj) {
+        return ISmsAppService.Stub.asInterface(obj);
+    }
+
+    @Override
+    protected String getServiceAction() {
+        return TelephonyManager.ACTION_SMS_APP_SERVICE;
+    }
+
+    @Override
+    protected String getServicePermission() {
+        return permission.BIND_SMS_APP_SERVICE;
+    }
+
+    @Override
+    public String getTargetPackage(int userId) {
+        final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(
+                mContext, /* updateIfNeeded= */ true, userId);
+        String ret = cn == null ? null : cn.getPackageName();
+
+        if (DEBUG) {
+            Slog.d(TAG, "getTargetPackage()=" + ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public void startMonitoring() {
+        final IntentFilter filter = new IntentFilter(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
+        mContext.registerReceiverAsUser(mSmsAppChangedWatcher, UserHandle.ALL, filter,
+                /* 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) {
+            if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
+                mListener.accept(SmsAppServiceFinder.this, getSendingUserId());
+            }
+        }
+    };
+}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 8caa702..f0ff570 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -627,6 +627,13 @@
     // If absolute volume is supported in AVRCP device
     private boolean mAvrcpAbsVolSupported = false;
 
+    // Pre-scale for Bluetooth Absolute Volume
+    private float[] mPrescaleAbsoluteVolume = new float[] {
+        0.5f,    // Pre-scale for index 1
+        0.7f,    // Pre-scale for index 2
+        0.85f,   // Pre-scale for index 3
+    };
+
     private static Long mLastDeviceConnectMsgTime = new Long(0);
 
     private NotificationManager mNm;
@@ -878,6 +885,23 @@
         mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
 
         mRecordMonitor.initMonitor();
+
+        final float[] preScale = new float[3];
+        preScale[0] = mContext.getResources().getFraction(
+                com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
+                1, 1);
+        preScale[1] = mContext.getResources().getFraction(
+                com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
+                1, 1);
+        preScale[2] = mContext.getResources().getFraction(
+                com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
+                1, 1);
+        for (int i = 0; i < preScale.length; i++) {
+            if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
+                mPrescaleAbsoluteVolume[i] = preScale[i];
+            }
+        }
+
     }
 
     public void systemReady() {
@@ -4661,7 +4685,9 @@
     @Override
     public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state)
     {
-        Log.i(TAG, "setBluetoothHearingAidDeviceConnectionState");
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
+                "setHearingAidDeviceConnectionState state=" + state
+                        + " addr=" + device.getAddress())).printLog(TAG));
 
         setBluetoothHearingAidDeviceConnectionState(
                 device, state,  false /* suppressNoisyIntent */, AudioSystem.DEVICE_NONE);
@@ -4699,12 +4725,12 @@
     public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice device,
                 int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)
     {
-        mDeviceLogger.log(new AudioEventLogger.StringEvent(
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
                 "setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent state=" + state
                 // only querying address as this is the only readily available field on the device
                 + " addr=" + device.getAddress()
                 + " prof=" + profile + " supprNoisy=" + suppressNoisyIntent
-                + " vol=" + a2dpVolume));
+                + " vol=" + a2dpVolume)).printLog(TAG));
         if (mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE, device)) {
             mDeviceLogger.log(new AudioEventLogger.StringEvent("A2DP connection state ignored"));
             return 0;
@@ -4926,18 +4952,12 @@
             if (index == 0) {
                 // 0% for volume 0
                 index = 0;
-            } else if (index == 1) {
-                // 50% for volume 1
-                index = (int)(mIndexMax * 0.5) /10;
-            } else if (index == 2) {
-                // 70% for volume 2
-                index = (int)(mIndexMax * 0.70) /10;
-            } else if (index == 3) {
-                // 85% for volume 3
-                index = (int)(mIndexMax * 0.85) /10;
+            } else if (index > 0 && index <= 3) {
+                // Pre-scale for volume steps 1 2 and 3
+                index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
             } else {
                 // otherwise, full gain
-                index = (mIndexMax + 5)/10;
+                index = (mIndexMax + 5) / 10;
             }
             return index;
         }
@@ -5870,6 +5890,8 @@
     }
 
     private void onSendBecomingNoisyIntent() {
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
+                "broadcast ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
         sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
     }
 
@@ -7235,7 +7257,7 @@
     // - wired: logged before onSetWiredDeviceConnectionState() is executed
     // - A2DP: logged at reception of method call
     final private AudioEventLogger mDeviceLogger = new AudioEventLogger(
-            LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP device connection");
+            LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
 
     final private AudioEventLogger mForceUseLogger = new AudioEventLogger(
             LOG_NB_EVENTS_FORCE_USE,
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index 6b09f1b..61836fdd 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -26,10 +26,14 @@
 import android.os.IBinder;
 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;
 
+import java.util.ArrayList;
+
 /**
  * A class to keep track of the authentication state for a given client.
  */
@@ -50,28 +54,68 @@
     public static final int LOCKOUT_TIMED = 1;
     public static final int LOCKOUT_PERMANENT = 2;
 
+    private final boolean mRequireConfirmation;
     // Callback mechanism received from the client
     // (BiometricPrompt -> BiometricPromptService -> <Biometric>Service -> AuthenticationClient)
     private IBiometricPromptReceiver mDialogReceiverFromClient;
     private Bundle mBundle;
     private IStatusBarService mStatusBarService;
     private boolean mInLockout;
+    private TokenEscrow mEscrow;
     protected boolean mDialogDismissed;
 
+    /**
+     * Container that holds the identifier and authToken. For biometrics that require user
+     * confirmation, these should not be sent to their final destinations until the user confirms.
+     */
+    class TokenEscrow {
+        final BiometricAuthenticator.Identifier mIdentifier;
+        final ArrayList<Byte> mToken;
+
+        TokenEscrow(BiometricAuthenticator.Identifier identifier, ArrayList<Byte> token) {
+            mIdentifier = identifier;
+            mToken = token;
+        }
+
+        BiometricAuthenticator.Identifier getIdentifier() {
+            return mIdentifier;
+        }
+
+        ArrayList<Byte> getToken() {
+            return mToken;
+        }
+    }
+
     // Receives events from SystemUI and handles them before forwarding them to BiometricDialog
     protected IBiometricPromptReceiver mDialogReceiver = new IBiometricPromptReceiver.Stub() {
         @Override // binder call
         public void onDialogDismissed(int reason) {
             if (mBundle != null && mDialogReceiverFromClient != null) {
                 try {
-                    mDialogReceiverFromClient.onDialogDismissed(reason);
+                    if (reason != BiometricPrompt.DISMISSED_REASON_POSITIVE) {
+                        // Positive button is used by passive modalities as a "confirm" button,
+                        // do not send to client
+                        mDialogReceiverFromClient.onDialogDismissed(reason);
+                    }
                     if (reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL) {
                         onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
                                 0 /* vendorCode */);
+                    } else if (reason == BiometricPrompt.DISMISSED_REASON_POSITIVE) {
+                        // Have the service send the token to KeyStore, and send onAuthenticated
+                        // to the application.
+                        if (mEscrow != null) {
+                            if (DEBUG) Slog.d(getLogTag(), "Confirmed");
+                            addTokenToKeyStore(mEscrow.getToken());
+                            notifyClientAuthenticationSucceeded(mEscrow.getIdentifier());
+                            mEscrow = null;
+                            onAuthenticationConfirmed();
+                        } else {
+                            Slog.e(getLogTag(), "Escrow is null!!!");
+                        }
                     }
                     mDialogDismissed = true;
                 } catch (RemoteException e) {
-                    Slog.e(getLogTag(), "Unable to notify dialog dismissed", e);
+                    Slog.e(getLogTag(), "Remote exception", e);
                 }
                 stop(true /* initiatedByClient */);
             }
@@ -89,11 +133,18 @@
      */
     public abstract void onStop();
 
+    /**
+     * This method is called when biometric authentication was confirmed by the user. The client
+     * should be removed.
+     */
+    public abstract void onAuthenticationConfirmed();
+
     public AuthenticationClient(Context context, Metrics metrics,
-            BiometricService.DaemonWrapper daemon, long halDeviceId, IBinder token,
-            BiometricService.ServiceListener listener, int targetUserId, int groupId, long opId,
+            BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
+            BiometricServiceBase.ServiceListener listener, int targetUserId, int groupId, long opId,
             boolean restricted, String owner, Bundle bundle,
-            IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService) {
+            IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService,
+            boolean requireConfirmation) {
         super(context, metrics, daemon, halDeviceId, token, listener, targetUserId, groupId,
                 restricted, owner);
         mOpId = opId;
@@ -101,6 +152,7 @@
         mDialogReceiverFromClient = dialogReceiver;
         mStatusBarService = statusBarService;
         mHandler = new Handler(Looper.getMainLooper());
+        mRequireConfirmation = requireConfirmation;
     }
 
     @Override
@@ -144,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) {
@@ -154,9 +206,52 @@
         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();
+        // Explicitly have if/else here to make it super obvious in case the code is
+        // touched in the future.
+        if (!getIsRestricted()) {
+            listener.onAuthenticationSucceeded(
+                    getHalDeviceId(), identifier, getTargetUserId());
+        } else {
+            listener.onAuthenticationSucceeded(
+                    getHalDeviceId(), null, getTargetUserId());
+        }
+    }
+
+    private void addTokenToKeyStore(ArrayList<Byte> token) {
+        // Send the token to KeyStore
+        final byte[] byteToken = new byte[token.size()];
+        for (int i = 0; i < token.size(); i++) {
+            byteToken[i] = token.get(i);
+        }
+        KeyStore.getInstance().addAuthToken(byteToken);
+    }
+
     @Override
     public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated) {
+            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);
+            } else {
+                addTokenToKeyStore(token);
+            }
+        }
+
         boolean result = false;
 
         // If the biometric dialog is showing, notify authentication succeeded
@@ -173,7 +268,7 @@
             }
         }
 
-        final BiometricService.ServiceListener listener = getListener();
+        final BiometricServiceBase.ServiceListener listener = getListener();
         if (listener != null) {
             try {
                 mMetricsLogger.action(mMetrics.actionBiometricAuth(), authenticated);
@@ -184,15 +279,8 @@
                         Slog.v(getLogTag(), "onAuthenticated(owner=" + getOwnerString()
                                 + ", id=" + identifier.getBiometricId());
                     }
-
-                    // Explicitly have if/else here to make it super obvious in case the code is
-                    // touched in the future.
-                    if (!getIsRestricted()) {
-                        listener.onAuthenticationSucceeded(
-                                getHalDeviceId(), identifier, getTargetUserId());
-                    } else {
-                        listener.onAuthenticationSucceeded(
-                                getHalDeviceId(), null, getTargetUserId());
+                    if (!mRequireConfirmation) {
+                        notifyClientAuthenticationSucceeded(identifier);
                     }
                 }
             } catch (RemoteException e) {
@@ -241,7 +329,8 @@
             if (listener != null) {
                 vibrateSuccess();
             }
-            result |= true; // we have a valid biometric, done
+            // we have a valid biometric that doesn't require confirmation, done
+            result |= !mRequireConfirmation;
             resetFailedAttempts();
             onStop();
         }
@@ -269,7 +358,7 @@
             if (mBundle != null) {
                 try {
                     mStatusBarService.showBiometricDialog(mBundle, mDialogReceiver,
-                            getBiometricType());
+                            getBiometricType(), mRequireConfirmation);
                 } catch (RemoteException e) {
                     Slog.e(getLogTag(), "Unable to show biometric dialog", e);
                 }
diff --git a/services/core/java/com/android/server/biometrics/BiometricPromptService.java b/services/core/java/com/android/server/biometrics/BiometricPromptService.java
deleted file mode 100644
index d1371d1..0000000
--- a/services/core/java/com/android/server/biometrics/BiometricPromptService.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics;
-
-import static android.Manifest.permission.USE_BIOMETRIC;
-import static android.Manifest.permission.USE_FINGERPRINT;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.IBiometricPromptReceiver;
-import android.hardware.biometrics.IBiometricPromptService;
-import android.hardware.biometrics.IBiometricPromptServiceReceiver;
-import android.hardware.face.FaceManager;
-import android.hardware.face.IFaceService;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IFingerprintService;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.util.Slog;
-
-import com.android.internal.R;
-import com.android.server.SystemService;
-
-import java.util.ArrayList;
-
-/**
- * System service that arbitrates the modality for BiometricPrompt to use.
- */
-public class BiometricPromptService extends SystemService {
-
-    private static final String TAG = "BiometricPromptService";
-
-    /**
-     * No biometric methods or nothing has been enrolled.
-     * Move/expose these in BiometricPrompt if we ever want to allow applications to "blacklist"
-     * modalities when calling authenticate().
-     */
-    private static final int BIOMETRIC_NONE = 0;
-
-    /**
-     * Constant representing fingerprint.
-     */
-    private static final int BIOMETRIC_FINGERPRINT = 1 << 0;
-
-    /**
-     * Constant representing iris.
-     */
-    private static final int BIOMETRIC_IRIS = 1 << 1;
-
-    /**
-     * Constant representing face.
-     */
-    private static final int BIOMETRIC_FACE = 1 << 2;
-
-    private static final int[] FEATURE_ID = {
-            BIOMETRIC_FINGERPRINT,
-            BIOMETRIC_IRIS,
-            BIOMETRIC_FACE
-    };
-
-    private final Handler mHandler;
-    private final boolean mHasFeatureFingerprint;
-    private final boolean mHasFeatureIris;
-    private final boolean mHasFeatureFace;
-
-    private IFingerprintService mFingerprintService;
-    private IFaceService mFaceService;
-
-    // Get and cache the available authenticator (manager) classes. Used since aidl doesn't support
-    // polymorphism :/
-    final ArrayList<Authenticator> mAuthenticators = new ArrayList<>();
-
-    // Cache the current service that's being used. This is the service which
-    // cancelAuthentication() must be forwarded to. This is just a cache, and the actual
-    // check (is caller the current client) is done in the <Biometric>Service.
-    // Since Settings/System (not application) is responsible for changing preference, this
-    // should be safe.
-    private int mCurrentModality;
-
-    private final class Authenticator {
-        int mType;
-        BiometricAuthenticator mAuthenticator;
-
-        Authenticator(int type, BiometricAuthenticator authenticator) {
-            mType = type;
-            mAuthenticator = authenticator;
-        }
-
-        int getType() {
-            return mType;
-        }
-
-        BiometricAuthenticator getAuthenticator() {
-            return mAuthenticator;
-        }
-    }
-
-    /**
-     * 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 IBiometricPromptService.Stub {
-
-        @Override // Binder call
-        public void authenticate(IBinder token, long sessionId, int userId,
-                IBiometricPromptServiceReceiver receiver, int flags, String opPackageName,
-                Bundle bundle, IBiometricPromptReceiver dialogReceiver) throws RemoteException {
-            // Check the USE_BIOMETRIC permission here. In the BiometricService, check do the
-            // AppOps and foreground check.
-            checkPermission();
-
-            if (token == null || receiver == null || opPackageName == null || bundle == null
-                    || dialogReceiver == null) {
-                Slog.e(TAG, "Unable to authenticate, one or more null arguments");
-                return;
-            }
-
-            final int callingUid = Binder.getCallingUid();
-            final int callingPid = Binder.getCallingPid();
-            final int callingUserId = UserHandle.getCallingUserId();
-
-            mHandler.post(() -> {
-                mCurrentModality = checkAndGetBiometricModality(receiver);
-
-                try {
-                    // No polymorphism :(
-                    if (mCurrentModality == BIOMETRIC_FINGERPRINT) {
-                        mFingerprintService.authenticateFromService(token, sessionId, userId,
-                                receiver, flags, opPackageName, bundle, dialogReceiver,
-                                callingUid, callingPid, callingUserId);
-                    } else if (mCurrentModality == BIOMETRIC_IRIS) {
-                        Slog.w(TAG, "Unsupported modality");
-                    } else if (mCurrentModality == BIOMETRIC_FACE) {
-                        mFaceService.authenticateFromService(token, sessionId, userId,
-                                receiver, flags, opPackageName, bundle, dialogReceiver,
-                                callingUid, callingPid, callingUserId);
-                    } else {
-                        Slog.w(TAG, "Unsupported modality");
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to start authentication", e);
-                }
-            });
-        }
-
-        @Override // Binder call
-        public void cancelAuthentication(IBinder token, String opPackageName)
-                throws RemoteException {
-            checkPermission();
-
-            if (token == null || opPackageName == null) {
-                Slog.e(TAG, "Unable to cancel, one or more null arguments");
-                return;
-            }
-
-            final int callingUid = Binder.getCallingUid();
-            final int callingPid = Binder.getCallingPid();
-            final int callingUserId = UserHandle.getCallingUserId();
-
-            mHandler.post(() -> {
-                try {
-                    if (mCurrentModality == BIOMETRIC_FINGERPRINT) {
-                        mFingerprintService.cancelAuthenticationFromService(token, opPackageName,
-                                callingUid, callingPid, callingUserId);
-                    } else if (mCurrentModality == BIOMETRIC_IRIS) {
-                        Slog.w(TAG, "Unsupported modality");
-                    } else if (mCurrentModality == BIOMETRIC_FACE) {
-                        mFaceService.cancelAuthenticationFromService(token, opPackageName,
-                                callingUid, callingPid, callingUserId);
-                    } else {
-                        Slog.w(TAG, "Unsupported modality");
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to cancel authentication");
-                }
-            });
-        }
-    }
-
-    private void checkPermission() {
-        if (getContext().checkCallingPermission(USE_FINGERPRINT)
-                != PackageManager.PERMISSION_GRANTED) {
-            getContext().enforceCallingPermission(USE_BIOMETRIC,
-                    "Must have USE_BIOMETRIC permission");
-        }
-    }
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public BiometricPromptService(Context context) {
-        super(context);
-
-        mHandler = new Handler(Looper.getMainLooper());
-
-        final PackageManager pm = context.getPackageManager();
-        mHasFeatureFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
-        mHasFeatureIris = pm.hasSystemFeature(PackageManager.FEATURE_IRIS);
-        mHasFeatureFace = pm.hasSystemFeature(PackageManager.FEATURE_FACE);
-    }
-
-    @Override
-    public void onStart() {
-        // TODO: maybe get these on-demand
-        if (mHasFeatureFingerprint) {
-            mFingerprintService = IFingerprintService.Stub.asInterface(
-                    ServiceManager.getService(Context.FINGERPRINT_SERVICE));
-        }
-        if (mHasFeatureFace) {
-            mFaceService = IFaceService.Stub.asInterface(
-                    ServiceManager.getService(Context.FACE_SERVICE));
-        }
-
-        // Cache the authenticators
-        for (int i = 0; i < FEATURE_ID.length; i++) {
-            if (hasFeature(FEATURE_ID[i])) {
-                Authenticator authenticator =
-                        new Authenticator(FEATURE_ID[i], getAuthenticator(FEATURE_ID[i]));
-                mAuthenticators.add(authenticator);
-            }
-        }
-
-        publishBinderService(Context.BIOMETRIC_PROMPT_SERVICE, new BiometricPromptServiceWrapper());
-    }
-
-    /**
-     * 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.
-     */
-    private int checkAndGetBiometricModality(IBiometricPromptServiceReceiver receiver) {
-        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;
-        }
-
-        // Find first authenticator that's both detected and enrolled
-        boolean isHardwareDetected = false;
-        boolean hasTemplatesEnrolled = false;
-        for (int i = 0; i < mAuthenticators.size(); i++) {
-            int featureId = mAuthenticators.get(i).getType();
-            BiometricAuthenticator authenticator = mAuthenticators.get(i).getAuthenticator();
-            if (authenticator.isHardwareDetected()) {
-                isHardwareDetected = true;
-                if (authenticator.hasEnrolledTemplates()) {
-                    hasTemplatesEnrolled = true;
-                    modality = featureId;
-                    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,
-                        hardwareUnavailable);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to send error", e);
-            }
-            return BIOMETRIC_NONE;
-        }
-
-        return modality;
-    }
-
-    private BiometricAuthenticator getAuthenticator(int type) {
-        switch (type) {
-            case BIOMETRIC_FINGERPRINT:
-                return (FingerprintManager)
-                        getContext().getSystemService(Context.FINGERPRINT_SERVICE);
-            case BIOMETRIC_IRIS:
-                return null;
-            case BIOMETRIC_FACE:
-                return (FaceManager)
-                        getContext().getSystemService(Context.FACE_SERVICE);
-            default:
-                return null;
-        }
-    }
-
-    private boolean hasFeature(int type) {
-        switch (type) {
-            case BIOMETRIC_FINGERPRINT:
-                return mHasFeatureFingerprint;
-            case BIOMETRIC_IRIS:
-                return mHasFeatureIris;
-            case BIOMETRIC_FACE:
-                return mHasFeatureFace;
-            default:
-                return false;
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 73c4223..b80dca6 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -11,508 +11,410 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT 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.biometrics;
 
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+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.ActivityTaskManager;
-import android.app.AlarmManager;
 import android.app.AppOpsManager;
-import android.app.IActivityTaskManager;
-import android.app.PendingIntent;
-import android.app.SynchronousUserSwitchObserver;
-import android.app.TaskStackListener;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
+import android.app.UserSwitchObserver;
+import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
+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.IBiometricServiceLockoutResetCallback;
-import android.hardware.fingerprint.Fingerprint;
+import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.IBiometricServiceReceiver;
+import android.hardware.face.FaceManager;
+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.IHwBinder;
-import android.os.IRemoteCallback;
-import android.os.PowerManager;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
 import android.os.UserHandle;
-import android.os.UserManager;
-import android.security.KeyStore;
+import android.provider.Settings;
+import android.util.Pair;
 import android.util.Slog;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
 
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.R;
 import com.android.server.SystemService;
-import com.android.server.biometrics.fingerprint.FingerprintService;
 
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 /**
- * Abstract base class containing all of the business logic for biometric services, e.g.
- * Fingerprint, Face, Iris.
- *
- * @hide
+ * System service that arbitrates the modality for BiometricPrompt to use.
  */
-public abstract class BiometricService extends SystemService implements IHwBinder.DeathRecipient {
+public class BiometricService extends SystemService {
 
-    protected static final boolean DEBUG = true;
+    private static final String TAG = "BiometricService";
 
-    private static final String KEY_LOCKOUT_RESET_USER = "lockout_reset_user";
-    private static final int MSG_USER_SWITCHING = 10;
-    private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30 * 1000;
-    private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
+    /**
+     * No biometric methods or nothing has been enrolled.
+     * Move/expose these in BiometricPrompt if we ever want to allow applications to "blacklist"
+     * modalities when calling authenticate().
+     */
+    private static final int BIOMETRIC_NONE = 0;
 
-    private final Context mContext;
-    private final String mKeyguardPackage;
+    /**
+     * Constant representing fingerprint.
+     */
+    private static final int BIOMETRIC_FINGERPRINT = 1 << 0;
+
+    /**
+     * Constant representing iris.
+     */
+    private static final int BIOMETRIC_IRIS = 1 << 1;
+
+    /**
+     * Constant representing face.
+     */
+    private static final int BIOMETRIC_FACE = 1 << 2;
+
+    private static final int[] FEATURE_ID = {
+            BIOMETRIC_FINGERPRINT,
+            BIOMETRIC_IRIS,
+            BIOMETRIC_FACE
+    };
+
     private final AppOpsManager mAppOps;
-    private final SparseBooleanArray mTimedLockoutCleared;
-    private final SparseIntArray mFailedAttempts;
-    private final IActivityTaskManager mActivityTaskManager;
-    private final AlarmManager mAlarmManager;
-    private final PowerManager mPowerManager;
-    private final UserManager mUserManager;
-    private final MetricsLogger mMetricsLogger;
-    private final BiometricTaskStackListener mTaskStackListener = new BiometricTaskStackListener();
-    private final ResetClientStateRunnable mResetClientState = new ResetClientStateRunnable();
-    private final LockoutReceiver mLockoutReceiver = new LockoutReceiver();
-    private final ArrayList<LockoutResetMonitor> mLockoutMonitors = new ArrayList<>();
+    private final Handler mHandler;
+    private final boolean mHasFeatureFingerprint;
+    private final boolean mHasFeatureIris;
+    private final boolean mHasFeatureFace;
+    private final SettingObserver mSettingObserver;
+    private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
 
-    protected final IStatusBarService mStatusBarService;
-    protected final Map<Integer, Long> mAuthenticatorIds =
-            Collections.synchronizedMap(new HashMap<>());
-    protected final ResetFailedAttemptsForUserRunnable mResetFailedAttemptsForCurrentUserRunnable =
-            new ResetFailedAttemptsForUserRunnable();
-    protected final H mHandler = new H();
+    private IFingerprintService mFingerprintService;
+    private IFaceService mFaceService;
 
-    private ClientMonitor mCurrentClient;
-    private ClientMonitor mPendingClient;
-    private PerformanceStats mPerformanceStats;
-    protected int mCurrentUserId = UserHandle.USER_NULL;
-    // Tracks if the current authentication makes use of CryptoObjects.
-    protected boolean mIsCrypto;
-    // Normal authentications are tracked by mPerformanceMap.
-    protected HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>();
-    // Transactions that make use of CryptoObjects are tracked by mCryptoPerformaceMap.
-    protected HashMap<Integer, PerformanceStats> mCryptoPerformanceMap = new HashMap<>();
+    // Get and cache the available authenticator (manager) classes. Used since aidl doesn't support
+    // polymorphism :/
+    final ArrayList<Authenticator> mAuthenticators = new ArrayList<>();
 
-    protected class PerformanceStats {
-        public int accept; // number of accepted biometrics
-        public int reject; // number of rejected biometrics
-        public int acquire; // total number of acquisitions. Should be >= accept+reject due to poor
-        // image acquisition in some cases (too fast, too slow, dirty sensor, etc.)
-        public int lockout; // total number of lockouts
-        public int permanentLockout; // total number of permanent lockouts
-    }
+    // Cache the current service that's being used. This is the service which
+    // cancelAuthentication() must be forwarded to. This is just a cache, and the actual
+    // check (is caller the current client) is done in the <Biometric>Service.
+    // Since Settings/System (not application) is responsible for changing preference, this
+    // should be safe.
+    private int mCurrentModality;
 
-    /**
-     * @return the log tag.
-     */
-    protected abstract String getTag();
+    private final class Authenticator {
+        int mType;
+        BiometricAuthenticator mAuthenticator;
 
-    /**
-     * @return the biometric utilities for a specific implementation.
-     */
-    protected abstract BiometricUtils getBiometricUtils();
-
-    /**
-     * @return the number of failed attempts after which the user will be temporarily locked out
-     *         from using the biometric. A strong auth (pin/pattern/pass) clears this counter.
-     */
-    protected abstract int getFailedAttemptsLockoutTimed();
-
-    /**
-     * @return the number of failed attempts after which the user will be permanently locked out
-     *         from using the biometric. A strong auth (pin/pattern/pass) clears this counter.
-     */
-    protected abstract int getFailedAttemptsLockoutPermanent();
-
-    /**
-     * @return the metrics constants for a biometric implementation.
-     */
-    protected abstract Metrics getMetrics();
-
-    /**
-     * @param userId
-     * @return true if the enrollment limit has been reached.
-     */
-    protected abstract boolean hasReachedEnrollmentLimit(int userId);
-
-    /**
-     * Notifies the HAL that the user has changed.
-     * @param userId
-     * @param clientPackage
-     */
-    protected abstract void updateActiveGroup(int userId, String clientPackage);
-
-    /**
-     * @return The protected intent to reset lockout for a specific biometric.
-     */
-    protected abstract String getLockoutResetIntent();
-
-    /**
-     * @return The permission the sender is required to have in order for the lockout reset intent
-     *         to be received by the BiometricService implementation.
-     */
-    protected abstract String getLockoutBroadcastPermission();
-
-    /**
-     * @return The HAL ID.
-     */
-    protected abstract long getHalDeviceId();
-
-    /**
-     * This method is called when the user switches. Implementations should probably notify the
-     * HAL.
-     * @param userId
-     */
-    protected abstract void handleUserSwitching(int userId);
-
-    /**
-     * @param userId
-     * @return Returns true if the user has any enrolled biometrics.
-     */
-    protected abstract boolean hasEnrolledBiometrics(int userId);
-
-    /**
-     * @return Returns the MANAGE_* permission string, which is required for enrollment, removal
-     * etc.
-     */
-    protected abstract String getManageBiometricPermission();
-
-    /**
-     * Checks if the caller has permission to use the biometric service - throws a SecurityException
-     * if not.
-     */
-    protected abstract void checkUseBiometricPermission();
-
-    /**
-     * @return Returns one of the {@link AppOpsManager} constants which pertains to the specific
-     *         biometric service.
-     */
-    protected abstract int getAppOp();
-
-
-    /**
-     * Notifies clients of any change in the biometric state (active / idle). This is mainly for
-     * Fingerprint navigation gestures.
-     * @param isActive
-     */
-    protected void notifyClientActiveCallbacks(boolean isActive) {}
-
-    protected abstract class AuthenticationClientImpl extends AuthenticationClient {
-
-        public AuthenticationClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
-                IBinder token, ServiceListener listener, int targetUserId, int groupId, long opId,
-                boolean restricted, String owner, Bundle bundle,
-                IBiometricPromptReceiver dialogReceiver,
-                IStatusBarService statusBarService) {
-            super(context, getMetrics(), daemon, halDeviceId, token, listener,
-                    targetUserId, groupId, opId, restricted, owner, bundle, dialogReceiver,
-                    statusBarService);
+        Authenticator(int type, BiometricAuthenticator authenticator) {
+            mType = type;
+            mAuthenticator = authenticator;
         }
 
-        @Override
-        public void onStart() {
-            try {
-                mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Could not register task stack listener", e);
-            }
+        int getType() {
+            return mType;
         }
 
-        @Override
-        public void onStop() {
-            try {
-                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Could not unregister task stack listener", e);
-            }
-        }
-
-        @Override
-        public void resetFailedAttempts() {
-            resetFailedAttemptsForUser(true /* clearAttemptCounter */,
-                    ActivityManager.getCurrentUser());
-        }
-
-        @Override
-        public void notifyUserActivity() {
-            userActivity();
-        }
-
-        @Override
-        public int handleFailedAttempt() {
-            final int currentUser = ActivityManager.getCurrentUser();
-            mFailedAttempts.put(currentUser, mFailedAttempts.get(currentUser, 0) + 1);
-            mTimedLockoutCleared.put(ActivityManager.getCurrentUser(), false);
-            final int lockoutMode = getLockoutMode();
-            if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
-                mPerformanceStats.permanentLockout++;
-            } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
-                mPerformanceStats.lockout++;
-            }
-
-            // Failing multiple times will continue to push out the lockout time
-            if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
-                scheduleLockoutResetForUser(currentUser);
-                return lockoutMode;
-            }
-            return AuthenticationClient.LOCKOUT_NONE;
+        BiometricAuthenticator getAuthenticator() {
+            return mAuthenticator;
         }
     }
 
-    protected class EnrollClientImpl extends EnrollClient {
+    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);
 
-        public EnrollClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
-                IBinder token, ServiceListener listener, int userId, int groupId,
-                byte[] cryptoToken, boolean restricted, String owner) {
-            super(context, getMetrics(), daemon, halDeviceId, token, listener,
-                    userId, groupId, cryptoToken, restricted, owner, getBiometricUtils());
+        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 notifyUserActivity() {
-            userActivity();
-        }
-    }
+        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;
 
-    protected class RemovalClientImpl extends RemovalClient {
-        private boolean mShouldNotify;
-
-        public RemovalClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
-                IBinder token, ServiceListener listener, int fingerId, int groupId, int userId,
-                boolean restricted, String owner) {
-            super(context, getMetrics(), daemon, halDeviceId, token, listener, fingerId, groupId,
-                    userId, restricted, owner, getBiometricUtils());
-        }
-
-        public void setShouldNotifyUserActivity(boolean shouldNotify) {
-            mShouldNotify = shouldNotify;
-        }
-
-        @Override
-        public void notifyUserActivity() {
-            if (mShouldNotify) {
-                userActivity();
-            }
-        }
-    }
-
-    protected class EnumerateClientImpl extends EnumerateClient {
-
-        public EnumerateClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
-                IBinder token, ServiceListener listener, int groupId, int userId,
-                boolean restricted, String owner) {
-            super(context, getMetrics(), daemon, halDeviceId, token, listener, groupId, userId,
-                    restricted, owner);
-        }
-
-        @Override
-        public void notifyUserActivity() {
-            userActivity();
-        }
-    }
-
-    /**
-     * Wraps the callback interface from Service -> Manager
-     */
-    protected interface ServiceListener {
-        default void onEnrollResult(BiometricAuthenticator.Identifier identifier,
-                int remaining) throws RemoteException {};
-
-        void onAcquired(long deviceId, int acquiredInfo, int vendorCode)
-                throws RemoteException;
-
-        void onAuthenticationSucceeded(long deviceId,
-                BiometricAuthenticator.Identifier biometric, int userId)
-                throws RemoteException;
-
-        void onAuthenticationFailed(long deviceId)
-                throws RemoteException;
-
-        void onError(long deviceId, int error, int vendorCode)
-                throws RemoteException;
-
-        default void onRemoved(BiometricAuthenticator.Identifier identifier,
-                int remaining) throws RemoteException {};
-
-        default void onEnumerated(BiometricAuthenticator.Identifier identifier,
-                int remaining) throws RemoteException {};
-    }
-
-    /**
-     * Wraps a portion of the interface from Service -> Daemon that is used by the ClientMonitor
-     * subclasses.
-     */
-    protected interface DaemonWrapper {
-        int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. see errno.h.
-        int authenticate(long operationId, int groupId) throws RemoteException;
-        int cancel() throws RemoteException;
-        int remove(int groupId, int biometricId) throws RemoteException;
-        int enumerate() throws RemoteException;
-        int enroll(byte[] cryptoToken, int groupId, int timeout) throws RemoteException;
-    }
-
-    /**
-     * Handler which all subclasses should post events to.
-     */
-    protected final class H extends Handler {
-        @Override
-        public void handleMessage(android.os.Message msg) {
-            switch (msg.what) {
-                case MSG_USER_SWITCHING:
-                    handleUserSwitching(msg.arg1);
-                    break;
-
-                default:
-                    Slog.w(getTag(), "Unknown message:" + msg.what);
-            }
-        }
-    }
-
-    private final class BiometricTaskStackListener extends TaskStackListener {
-        @Override
-        public void onTaskStackChanged() {
-            try {
-                if (!(mCurrentClient instanceof AuthenticationClient)) {
-                    return;
+                List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks;
+                for (int i = 0; i < callbacks.size(); i++) {
+                    callbacks.get(i).notify(BiometricSourceType.FACE, mFaceEnabledOnKeyguard);
                 }
-                final String currentClient = mCurrentClient.getOwnerString();
-                if (isKeyguard(currentClient)) {
-                    return; // Keyguard is always allowed
-                }
-                List<ActivityManager.RunningTaskInfo> runningTasks =
-                        mActivityTaskManager.getTasks(1);
-                if (!runningTasks.isEmpty()) {
-                    final String topPackage = runningTasks.get(0).topActivity.getPackageName();
-                    if (!topPackage.contentEquals(currentClient)) {
-                        Slog.e(getTag(), "Stopping background authentication, top: " + topPackage
-                                + " currentClient: " + currentClient);
-                        mCurrentClient.stop(false /* initiatedByClient */);
-                    }
-                }
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Unable to get running tasks", e);
+            } 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;
             }
         }
-    }
 
-    private final class ResetClientStateRunnable implements Runnable {
-        @Override
-        public void run() {
-            /**
-             * Warning: if we get here, the driver never confirmed our call to cancel the current
-             * operation (authenticate, enroll, remove, enumerate, etc), which is
-             * really bad.  The result will be a 3-second delay in starting each new client.
-             * If you see this on a device, make certain the driver notifies with
-             * {@link BiometricConstants#BIOMETRIC_ERROR_CANCELED} in response to cancel()
-             * once it has successfully switched to the IDLE state in the HAL.
-             * Additionally,{@link BiometricConstants#BIOMETRIC_ERROR_CANCELED} should only be sent
-             * in response to an actual cancel() call.
-             */
-            Slog.w(getTag(), "Client "
-                    + (mCurrentClient != null ? mCurrentClient.getOwnerString() : "null")
-                    + " failed to respond to cancel, starting client "
-                    + (mPendingClient != null ? mPendingClient.getOwnerString() : "null"));
+        boolean getFaceEnabledOnKeyguard() {
+            return mFaceEnabledOnKeyguard;
+        }
 
-            mCurrentClient = null;
-            startClient(mPendingClient, false);
+        boolean getFaceEnabledForApps() {
+            return mFaceEnabledForApps;
         }
     }
 
-    private final class LockoutReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Slog.v(getTag(), "Resetting lockout: " + intent.getAction());
-            if (getLockoutResetIntent().equals(intent.getAction())) {
-                final int user = intent.getIntExtra(KEY_LOCKOUT_RESET_USER, 0);
-                resetFailedAttemptsForUser(false /* clearAttemptCounter */, user);
-            }
-        }
-    }
+    private final class EnabledOnKeyguardCallback implements IBinder.DeathRecipient {
 
-    private final class ResetFailedAttemptsForUserRunnable implements Runnable {
-        @Override
-        public void run() {
-            resetFailedAttemptsForUser(true /* clearAttemptCounter */,
-                    ActivityManager.getCurrentUser());
-        }
-    }
+        private final IBiometricEnabledOnKeyguardCallback mCallback;
 
-    private final class LockoutResetMonitor implements IBinder.DeathRecipient {
-        private static final long WAKELOCK_TIMEOUT_MS = 2000;
-        private final IBiometricServiceLockoutResetCallback mCallback;
-        private final PowerManager.WakeLock mWakeLock;
-
-        public LockoutResetMonitor(IBiometricServiceLockoutResetCallback callback) {
+        EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) {
             mCallback = callback;
-            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                    "lockout reset callback");
             try {
-                mCallback.asBinder().linkToDeath(LockoutResetMonitor.this, 0);
+                mCallback.asBinder().linkToDeath(EnabledOnKeyguardCallback.this, 0);
             } catch (RemoteException e) {
-                Slog.w(getTag(), "caught remote exception in linkToDeath", e);
+                Slog.w(TAG, "Unable to linkToDeath", e);
             }
         }
 
-        public void sendLockoutReset() {
-            if (mCallback != null) {
-                try {
-                    mWakeLock.acquire(WAKELOCK_TIMEOUT_MS);
-                    mCallback.onLockoutReset(getHalDeviceId(), new IRemoteCallback.Stub() {
-                        @Override
-                        public void sendResult(Bundle data) throws RemoteException {
-                            releaseWakelock();
-                        }
-                    });
-                } catch (DeadObjectException e) {
-                    Slog.w(getTag(), "Death object while invoking onLockoutReset: ", e);
-                    mHandler.post(mRemoveCallbackRunnable);
-                } catch (RemoteException e) {
-                    Slog.w(getTag(), "Failed to invoke onLockoutReset: ", e);
-                    releaseWakelock();
-                }
+        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);
             }
         }
 
-        private final Runnable mRemoveCallbackRunnable = new Runnable() {
-            @Override
-            public void run() {
-                releaseWakelock();
-                removeLockoutResetCallback(LockoutResetMonitor.this);
-            }
-        };
-
         @Override
         public void binderDied() {
-            Slog.e(getTag(), "Lockout reset callback binder died");
-            mHandler.post(mRemoveCallbackRunnable);
+            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 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 BiometricServiceBase, check do the
+            // AppOps and foreground check.
+            checkPermission();
+
+            if (token == null || receiver == null || opPackageName == null || bundle == null
+                    || dialogReceiver == null) {
+                Slog.e(TAG, "Unable to authenticate, one or more null arguments");
+                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(() -> {
+                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) {
+                        mFingerprintService.authenticateFromService(token, sessionId, userId,
+                                receiver, flags, opPackageName, bundle, dialogReceiver,
+                                callingUid, callingPid, callingUserId);
+                    } else if (mCurrentModality == BIOMETRIC_IRIS) {
+                        Slog.w(TAG, "Unsupported modality");
+                    } else if (mCurrentModality == BIOMETRIC_FACE) {
+                        mFaceService.authenticateFromService(true /* requireConfirmation */,
+                                token, sessionId, userId, receiver, flags, opPackageName,
+                                bundle, dialogReceiver, callingUid, callingPid, callingUserId);
+                    } else {
+                        Slog.w(TAG, "Unsupported modality");
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to start authentication", e);
+                }
+            });
         }
 
-        private void releaseWakelock() {
-            if (mWakeLock.isHeld()) {
-                mWakeLock.release();
+        @Override // Binder call
+        public void cancelAuthentication(IBinder token, String opPackageName)
+                throws RemoteException {
+            checkPermission();
+
+            if (token == null || opPackageName == null) {
+                Slog.e(TAG, "Unable to cancel, one or more null arguments");
+                return;
             }
+
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
+            final int callingUserId = UserHandle.getCallingUserId();
+
+            mHandler.post(() -> {
+                try {
+                    if (mCurrentModality == BIOMETRIC_FINGERPRINT) {
+                        mFingerprintService.cancelAuthenticationFromService(token, opPackageName,
+                                callingUid, callingPid, callingUserId);
+                    } else if (mCurrentModality == BIOMETRIC_IRIS) {
+                        Slog.w(TAG, "Unsupported modality");
+                    } else if (mCurrentModality == BIOMETRIC_FACE) {
+                        mFaceService.cancelAuthenticationFromService(token, opPackageName,
+                                callingUid, callingPid, callingUserId);
+                    } else {
+                        Slog.w(TAG, "Unsupported modality");
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to cancel authentication");
+                }
+            });
+        }
+
+        @Override // Binder call
+        public int canAuthenticate(String opPackageName) {
+            checkPermission();
+            checkAppOp(opPackageName, Binder.getCallingUid());
+
+            final int userId = UserHandle.getCallingUserId();
+            final long ident = Binder.clearCallingIdentity();
+            int error;
+            try {
+                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++) {
+                    mAuthenticators.get(i).getAuthenticator().setActiveUser(userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    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) {
+            getContext().enforceCallingPermission(USE_BIOMETRIC,
+                    "Must have USE_BIOMETRIC permission");
         }
     }
 
@@ -527,589 +429,174 @@
      */
     public BiometricService(Context context) {
         super(context);
-        mContext = context;
-        mStatusBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
-                com.android.internal.R.string.config_keyguardComponent)).getPackageName();
+
         mAppOps = context.getSystemService(AppOpsManager.class);
-        mTimedLockoutCleared = new SparseBooleanArray();
-        mFailedAttempts = new SparseIntArray();
-        mActivityTaskManager = ((ActivityTaskManager) context.getSystemService(
-                Context.ACTIVITY_TASK_SERVICE)).getService();
-        mPowerManager = mContext.getSystemService(PowerManager.class);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mUserManager = UserManager.get(mContext);
-        mMetricsLogger = new MetricsLogger();
-        mContext.registerReceiver(mLockoutReceiver, new IntentFilter(getLockoutResetIntent()),
-                getLockoutBroadcastPermission(), null /* handler */);
+        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
     public void onStart() {
-        listenForUserSwitches();
-    }
+        // TODO: maybe get these on-demand
+        if (mHasFeatureFingerprint) {
+            mFingerprintService = IFingerprintService.Stub.asInterface(
+                    ServiceManager.getService(Context.FINGERPRINT_SERVICE));
+        }
+        if (mHasFeatureFace) {
+            mFaceService = IFaceService.Stub.asInterface(
+                    ServiceManager.getService(Context.FACE_SERVICE));
+        }
 
-    @Override
-    public void serviceDied(long cookie) {
-        Slog.e(getTag(), "HAL died");
-        mMetricsLogger.count(getMetrics().tagHalDied(), 1);
-        handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                0 /*vendorCode */);
-    }
+        // Cache the authenticators
+        for (int i = 0; i < FEATURE_ID.length; i++) {
+            if (hasFeature(FEATURE_ID[i])) {
+                Authenticator authenticator =
+                        new Authenticator(FEATURE_ID[i], getAuthenticator(FEATURE_ID[i]));
+                mAuthenticators.add(authenticator);
+            }
+        }
 
-    protected ClientMonitor getCurrentClient() {
-        return mCurrentClient;
-    }
-
-    protected ClientMonitor getPendingClient() {
-        return mPendingClient;
+        publishBinderService(Context.BIOMETRIC_SERVICE, new BiometricServiceWrapper());
     }
 
     /**
-     * Callback handlers from the daemon. The caller must put this on a handler.
-     */
-
-    protected void handleAcquired(long deviceId, int acquiredInfo, int vendorCode) {
-        ClientMonitor client = mCurrentClient;
-        if (client != null && client.onAcquired(acquiredInfo, vendorCode)) {
-            removeClient(client);
-        }
-        if (mPerformanceStats != null && getLockoutMode() == AuthenticationClient.LOCKOUT_NONE
-                && client instanceof AuthenticationClient) {
-            // ignore enrollment acquisitions or acquisitions when we're locked out
-            mPerformanceStats.acquire++;
-        }
-    }
-
-    protected void handleAuthenticated(BiometricAuthenticator.Identifier identifier,
-            ArrayList<Byte> token) {
-        ClientMonitor client = mCurrentClient;
-        final boolean authenticated = identifier.getBiometricId() != 0;
-
-        if (authenticated) {
-            final byte[] byteToken = new byte[token.size()];
-            for (int i = 0; i < token.size(); i++) {
-                byteToken[i] = token.get(i);
-            }
-            KeyStore.getInstance().addAuthToken(byteToken);
-        }
-        if (client != null && client.onAuthenticated(identifier, authenticated)) {
-            removeClient(client);
-        }
-        if (authenticated) {
-            mPerformanceStats.accept++;
-        } else {
-            mPerformanceStats.reject++;
-        }
-    }
-
-    protected void handleEnrollResult(BiometricAuthenticator.Identifier identifier,
-            int remaining) {
-        ClientMonitor client = mCurrentClient;
-        if (client != null && client.onEnrollResult(identifier, remaining)) {
-            removeClient(client);
-            // When enrollment finishes, update this group's authenticator id, as the HAL has
-            // already generated a new authenticator id when the new biometric is enrolled.
-            if (identifier instanceof Fingerprint) {
-                updateActiveGroup(((Fingerprint)identifier).getGroupId(), null);
-            } else {
-                updateActiveGroup(mCurrentUserId, null);
-            }
-
-        }
-    }
-
-    protected void handleError(long deviceId, int error, int vendorCode) {
-        final ClientMonitor client = mCurrentClient;
-
-        if (DEBUG) Slog.v(getTag(), "handleError(client="
-                + (client != null ? client.getOwnerString() : "null") + ", error = " + error + ")");
-
-        if (client != null && client.onError(deviceId, error, vendorCode)) {
-            removeClient(client);
-        }
-
-        if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
-            mHandler.removeCallbacks(mResetClientState);
-            if (mPendingClient != null) {
-                if (DEBUG) Slog.v(getTag(), "start pending client " + mPendingClient.getOwnerString());
-                startClient(mPendingClient, false);
-                mPendingClient = null;
-            }
-        }
-    }
-
-    protected void handleRemoved(BiometricAuthenticator.Identifier identifier,
-            final int remaining) {
-        if (DEBUG) Slog.w(getTag(), "Removed: fid=" + identifier.getBiometricId()
-                + ", dev=" + identifier.getDeviceId()
-                + ", rem=" + remaining);
-
-        ClientMonitor client = mCurrentClient;
-        if (client != null && client.onRemoved(identifier, remaining)) {
-            removeClient(client);
-            // When the last biometric of a group is removed, update the authenticator id
-            int userId = mCurrentUserId;
-            if (identifier instanceof Fingerprint) {
-                userId = ((Fingerprint) identifier).getGroupId();
-            }
-            if (!hasEnrolledBiometrics(userId)) {
-                updateActiveGroup(userId, null);
-            }
-        }
-    }
-
-    /**
-     * Calls from the Manager. These are still on the calling binder's thread.
-     */
-
-    protected void enrollInternal(EnrollClientImpl client, int userId) {
-        if (hasReachedEnrollmentLimit(userId)) {
-            return;
-        }
-
-        // Group ID is arbitrarily set to parent profile user ID. It just represents
-        // the default biometrics for the user.
-        if (!isCurrentUserOrProfile(userId)) {
-            return;
-        }
-
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    protected void cancelEnrollmentInternal(IBinder token) {
-        mHandler.post(() -> {
-            ClientMonitor client = mCurrentClient;
-            if (client instanceof EnrollClient && client.getToken() == token) {
-                client.stop(client.getToken() == token);
-            }
-        });
-    }
-
-    protected void authenticateInternal(AuthenticationClientImpl client, long opId,
-            String opPackageName) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingPid = Binder.getCallingPid();
-        final int callingUserId = UserHandle.getCallingUserId();
-        authenticateInternal(client, opId, opPackageName, callingUid, callingPid, callingUserId);
-    }
-
-    protected void authenticateInternal(AuthenticationClientImpl client, long opId,
-            String opPackageName, int callingUid, int callingPid, int callingUserId) {
-        if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
-                callingUserId)) {
-            if (DEBUG) Slog.v(getTag(), "authenticate(): reject " + opPackageName);
-            return;
-        }
-
-        mHandler.post(() -> {
-            mMetricsLogger.histogram(getMetrics().tagAuthToken(), opId != 0L ? 1 : 0);
-
-            // Get performance stats object for this user.
-            HashMap<Integer, PerformanceStats> pmap
-                    = (opId == 0) ? mPerformanceMap : mCryptoPerformanceMap;
-            PerformanceStats stats = pmap.get(mCurrentUserId);
-            if (stats == null) {
-                stats = new PerformanceStats();
-                pmap.put(mCurrentUserId, stats);
-            }
-            mPerformanceStats = stats;
-            mIsCrypto = (opId != 0);
-
-            startAuthentication(client, opPackageName);
-        });
-    }
-
-    protected void cancelAuthenticationInternal(final IBinder token, final String opPackageName) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingPid = Binder.getCallingPid();
-        final int callingUserId = UserHandle.getCallingUserId();
-        cancelAuthenticationInternal(token, opPackageName, callingUid, callingPid, callingUserId);
-    }
-
-    protected void cancelAuthenticationInternal(final IBinder token, final String opPackageName,
-            int callingUid, int callingPid, int callingUserId) {
-        if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
-                callingUserId)) {
-            if (DEBUG) Slog.v(getTag(), "cancelAuthentication(): reject " + opPackageName);
-            return;
-        }
-
-        mHandler.post(() -> {
-            ClientMonitor client = mCurrentClient;
-            if (client instanceof AuthenticationClient) {
-                if (client.getToken() == token) {
-                    if (DEBUG) Slog.v(getTag(), "stop client " + client.getOwnerString());
-                    client.stop(client.getToken() == token);
-                } else {
-                    if (DEBUG) Slog.v(getTag(), "can't stop client "
-                            + client.getOwnerString() + " since tokens don't match");
-                }
-            } else if (client != null) {
-                if (DEBUG) Slog.v(getTag(), "can't cancel non-authenticating client "
-                        + client.getOwnerString());
-            }
-        });
-    }
-
-    protected void setActiveUserInternal(int userId) {
-        mHandler.post(() -> {
-            updateActiveGroup(userId, null /* clientPackage */);
-        });
-    }
-
-    protected void removeInternal(RemovalClientImpl client) {
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    protected void enumerateInternal(EnumerateClientImpl client) {
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    // Should be done on a handler thread - not on the Binder's thread.
-    private void startAuthentication(AuthenticationClientImpl client, String opPackageName) {
-        updateActiveGroup(client.getGroupId(), opPackageName);
-
-        if (DEBUG) Slog.v(getTag(), "startAuthentication(" + opPackageName + ")");
-
-        int lockoutMode = getLockoutMode();
-        if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
-            Slog.v(getTag(), "In lockout mode(" + lockoutMode +
-                    ") ; disallowing authentication");
-            int errorCode = lockoutMode == AuthenticationClient.LOCKOUT_TIMED ?
-                    BiometricConstants.BIOMETRIC_ERROR_LOCKOUT :
-                    BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
-            if (!client.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */)) {
-                Slog.w(getTag(), "Cannot send permanent lockout message to client");
-            }
-            return;
-        }
-        startClient(client, true /* initiatedByClient */);
-    }
-
-    protected void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback) {
-        mHandler.post(() -> {
-           final LockoutResetMonitor monitor = new LockoutResetMonitor(callback);
-           if (!mLockoutMonitors.contains(monitor)) {
-               mLockoutMonitors.add(monitor);
-           }
-        });
-    }
-
-    /**
-     * Helper methods.
-     */
-
-    /**
-     * @param opPackageName name of package for caller
-     * @param requireForeground only allow this call while app is in the foreground
-     * @return true if caller can use the biometric API
-     */
-    protected boolean canUseBiometric(String opPackageName, boolean requireForeground, int uid,
-            int pid, int userId) {
-        checkUseBiometricPermission();
-
-        if (isKeyguard(opPackageName)) {
-            return true; // Keyguard is always allowed
-        }
-        if (!isCurrentUserOrProfile(userId)) {
-            Slog.w(getTag(), "Rejecting " + opPackageName + "; not a current user or profile");
-            return false;
-        }
-        if (mAppOps.noteOp(getAppOp(), uid, opPackageName) != AppOpsManager.MODE_ALLOWED) {
-            Slog.w(getTag(), "Rejecting " + opPackageName + "; permission denied");
-            return false;
-        }
-        if (requireForeground && !(isForegroundActivity(uid, pid) || isCurrentClient(
-                opPackageName))) {
-            Slog.w(getTag(), "Rejecting " + opPackageName + "; not in foreground");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * @param opPackageName package of the caller
-     * @return true if this is the same client currently using the biometric
-     */
-    private boolean isCurrentClient(String opPackageName) {
-        return mCurrentClient != null && mCurrentClient.getOwnerString().equals(opPackageName);
-    }
-
-    /**
-     * @return true if this is keyguard package
-     */
-    private boolean isKeyguard(String clientPackage) {
-        return mKeyguardPackage.equals(clientPackage);
-    }
-
-    protected int getLockoutMode() {
-        final int currentUser = ActivityManager.getCurrentUser();
-        final int failedAttempts = mFailedAttempts.get(currentUser, 0);
-        if (failedAttempts >= getFailedAttemptsLockoutPermanent()) {
-            return AuthenticationClient.LOCKOUT_PERMANENT;
-        } else if (failedAttempts > 0 &&
-                mTimedLockoutCleared.get(currentUser, false) == false
-                && (failedAttempts % getFailedAttemptsLockoutTimed() == 0)) {
-            return AuthenticationClient.LOCKOUT_TIMED;
-        }
-        return AuthenticationClient.LOCKOUT_NONE;
-    }
-
-    private boolean isForegroundActivity(int uid, int pid) {
-        try {
-            List<ActivityManager.RunningAppProcessInfo> procs =
-                    ActivityManager.getService().getRunningAppProcesses();
-            int N = procs.size();
-            for (int i = 0; i < N; i++) {
-                ActivityManager.RunningAppProcessInfo proc = procs.get(i);
-                if (proc.pid == pid && proc.uid == uid
-                        && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) {
-                    return true;
-                }
-            }
-        } catch (RemoteException e) {
-            Slog.w(getTag(), "am.getRunningAppProcesses() failed");
-        }
-        return false;
-    }
-
-    /**
-     * Calls the HAL to switch states to the new task. If there's already a current task,
-     * it calls cancel() and sets mPendingClient to begin when the current task finishes
-     * ({@link BiometricConstants#BIOMETRIC_ERROR_CANCELED}).
+     * 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.
      *
-     * @param newClient the new client that wants to connect
-     * @param initiatedByClient true for authenticate, remove and enroll
+     * @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 void startClient(ClientMonitor newClient, boolean initiatedByClient) {
-        ClientMonitor currentClient = mCurrentClient;
-        if (currentClient != null) {
-            if (DEBUG) Slog.v(getTag(), "request stop current client " +
-                    currentClient.getOwnerString());
+    private Pair<Integer, Integer> checkAndGetBiometricModality(int callingUid) {
+        int modality = BIOMETRIC_NONE;
 
-            // This check only matters for FingerprintService, since enumerate may call back
-            // multiple times.
-            if (currentClient instanceof FingerprintService.EnumerateClientImpl ||
-                    currentClient instanceof FingerprintService.RemovalClientImpl) {
-                // This condition means we're currently running internal diagnostics to
-                // remove extra fingerprints in the hardware and/or the software
-                // TODO: design an escape hatch in case client never finishes
-                if (newClient != null) {
-                    Slog.w(getTag(), "Internal cleanup in progress but trying to start client "
-                            + newClient.getClass().getSuperclass().getSimpleName()
-                            + "(" + newClient.getOwnerString() + ")"
-                            + ", initiatedByClient = " + initiatedByClient);
+        // No biometric features, send error
+        if (mAuthenticators.isEmpty()) {
+            return new Pair<>(BIOMETRIC_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT);
+        }
+
+        // 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++) {
+            modality = mAuthenticators.get(i).getType();
+            BiometricAuthenticator authenticator = mAuthenticators.get(i).getAuthenticator();
+            if (authenticator.isHardwareDetected()) {
+                isHardwareDetected = true;
+                if (firstHwAvailable == BIOMETRIC_NONE) {
+                    // Store the first one since we want to return the error in correct priority
+                    // order.
+                    firstHwAvailable = modality;
                 }
-            } else {
-                currentClient.stop(initiatedByClient);
-            }
-            mPendingClient = newClient;
-            mHandler.removeCallbacks(mResetClientState);
-            mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
-        } else if (newClient != null) {
-            mCurrentClient = newClient;
-            if (DEBUG) Slog.v(getTag(), "starting client "
-                    + newClient.getClass().getSuperclass().getSimpleName()
-                    + "(" + newClient.getOwnerString() + ")"
-                    + ", initiatedByClient = " + initiatedByClient);
-            notifyClientActiveCallbacks(true);
-
-            newClient.start();
-        }
-    }
-
-    protected void removeClient(ClientMonitor client) {
-        if (client != null) {
-            client.destroy();
-            if (client != mCurrentClient && mCurrentClient != null) {
-                Slog.w(getTag(), "Unexpected client: " + client.getOwnerString() + "expected: "
-                        + mCurrentClient.getOwnerString());
-            }
-        }
-        if (mCurrentClient != null) {
-            if (DEBUG) Slog.v(getTag(), "Done with client: " + client.getOwnerString());
-            mCurrentClient = null;
-        }
-        if (mPendingClient == null) {
-            notifyClientActiveCallbacks(false);
-        }
-    }
-
-    /**
-     * Populates existing authenticator ids. To be used only during the start of the service.
-     */
-    protected void loadAuthenticatorIds() {
-        // This operation can be expensive, so keep track of the elapsed time. Might need to move to
-        // background if it takes too long.
-        long t = System.currentTimeMillis();
-        mAuthenticatorIds.clear();
-        for (UserInfo user : UserManager.get(getContext()).getUsers(true /* excludeDying */)) {
-            int userId = getUserOrWorkProfileId(null, user.id);
-            if (!mAuthenticatorIds.containsKey(userId)) {
-                updateActiveGroup(userId, null);
-            }
-        }
-
-        t = System.currentTimeMillis() - t;
-        if (t > 1000) {
-            Slog.w(getTag(), "loadAuthenticatorIds() taking too long: " + t + "ms");
-        }
-    }
-
-    /**
-     * @param clientPackage the package of the caller
-     * @return the profile id
-     */
-    protected int getUserOrWorkProfileId(String clientPackage, int userId) {
-        if (!isKeyguard(clientPackage) && isWorkProfile(userId)) {
-            return userId;
-        }
-        return getEffectiveUserId(userId);
-    }
-
-    protected boolean isRestricted() {
-        // Only give privileged apps (like Settings) access to biometric info
-        final boolean restricted = !hasPermission(getManageBiometricPermission());
-        return restricted;
-    }
-
-    protected boolean hasPermission(String permission) {
-        return getContext().checkCallingOrSelfPermission(permission)
-                == PackageManager.PERMISSION_GRANTED;
-    }
-
-    protected void checkPermission(String permission) {
-        getContext().enforceCallingOrSelfPermission(permission,
-                "Must have " + permission + " permission.");
-    }
-
-    protected boolean isCurrentUserOrProfile(int userId) {
-        UserManager um = UserManager.get(mContext);
-        if (um == null) {
-            Slog.e(getTag(), "Unable to acquire UserManager");
-            return false;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            // Allow current user or profiles of the current user...
-            for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
-                if (profileId == userId) {
-                    return true;
+                if (authenticator.hasEnrolledTemplates(callingUid)) {
+                    hasTemplatesEnrolled = true;
+                    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;
+                    }
                 }
             }
-        } finally {
-            Binder.restoreCallingIdentity(token);
         }
 
-        return false;
-    }
-
-    /***
-     * @param opPackageName the name of the calling package
-     * @return authenticator id for the calling user
-     */
-    protected long getAuthenticatorId(String opPackageName) {
-        final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId());
-        return mAuthenticatorIds.getOrDefault(userId, 0L);
-    }
-
-    private void scheduleLockoutResetForUser(int userId) {
-        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + FAIL_LOCKOUT_TIMEOUT_MS,
-                getLockoutResetIntentForUser(userId));
-    }
-
-    private PendingIntent getLockoutResetIntentForUser(int userId) {
-        return PendingIntent.getBroadcast(mContext, userId,
-                new Intent(getLockoutResetIntent()).putExtra(KEY_LOCKOUT_RESET_USER, userId),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    private void userActivity() {
-        long now = SystemClock.uptimeMillis();
-        mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
-    }
-
-    /**
-     * @param userId
-     * @return true if this is a work profile
-     */
-    private boolean isWorkProfile(int userId) {
-        UserInfo userInfo = null;
-        final long token = Binder.clearCallingIdentity();
-        try {
-            userInfo = mUserManager.getUserInfo(userId);
-        } finally {
-            Binder.restoreCallingIdentity(token);
+        // Check error conditions
+        if (!isHardwareDetected) {
+            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 userInfo != null && userInfo.isManagedProfile();
+
+        return new Pair<>(modality, BiometricConstants.BIOMETRIC_ERROR_NONE);
     }
 
-
-    private int getEffectiveUserId(int userId) {
-        UserManager um = UserManager.get(mContext);
-        if (um != null) {
-            final long callingIdentity = Binder.clearCallingIdentity();
-            userId = um.getCredentialOwnerProfile(userId);
-            Binder.restoreCallingIdentity(callingIdentity);
-        } else {
-            Slog.e(getTag(), "Unable to acquire UserManager");
-        }
-        return userId;
-    }
-
-    // Attempt counter should only be cleared when Keyguard goes away or when
-    // a biometric is successfully authenticated.
-    private void resetFailedAttemptsForUser(boolean clearAttemptCounter, int userId) {
-        if (DEBUG && getLockoutMode() != AuthenticationClient.LOCKOUT_NONE) {
-            Slog.v(getTag(), "Reset biometric lockout, clearAttemptCounter=" + clearAttemptCounter);
-        }
-        if (clearAttemptCounter) {
-            mFailedAttempts.put(userId, 0);
-        }
-        mTimedLockoutCleared.put(userId, true);
-        // If we're asked to reset failed attempts externally (i.e. from Keyguard),
-        // the alarm might still be pending; remove it.
-        cancelLockoutResetForUser(userId);
-        notifyLockoutResetMonitors();
-    }
-
-    private void cancelLockoutResetForUser(int userId) {
-        mAlarmManager.cancel(getLockoutResetIntentForUser(userId));
-    }
-
-    private void listenForUserSwitches() {
-        try {
-            ActivityManager.getService().registerUserSwitchObserver(
-                    new SynchronousUserSwitchObserver() {
-                        @Override
-                        public void onUserSwitching(int newUserId) throws RemoteException {
-                            mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
-                                    .sendToTarget();
-                        }
-                    }, getTag());
-        } catch (RemoteException e) {
-            Slog.w(getTag(), "Failed to listen for user switching event" ,e);
+    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 void notifyLockoutResetMonitors() {
-        for (int i = 0; i < mLockoutMonitors.size(); i++) {
-            mLockoutMonitors.get(i).sendLockoutReset();
+    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 void removeLockoutResetCallback(
-            LockoutResetMonitor monitor) {
-        mLockoutMonitors.remove(monitor);
+    private BiometricAuthenticator getAuthenticator(int type) {
+        switch (type) {
+            case BIOMETRIC_FINGERPRINT:
+                return (FingerprintManager)
+                        getContext().getSystemService(Context.FINGERPRINT_SERVICE);
+            case BIOMETRIC_IRIS:
+                return null;
+            case BIOMETRIC_FACE:
+                return (FaceManager)
+                        getContext().getSystemService(Context.FACE_SERVICE);
+            default:
+                return null;
+        }
+    }
+
+    private boolean hasFeature(int type) {
+        switch (type) {
+            case BIOMETRIC_FINGERPRINT:
+                return mHasFeatureFingerprint;
+            case BIOMETRIC_IRIS:
+                return mHasFeatureIris;
+            case BIOMETRIC_FACE:
+                return mHasFeatureFace;
+            default:
+                return false;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
new file mode 100644
index 0000000..74d742a
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics;
+
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.AlarmManager;
+import android.app.AppOpsManager;
+import android.app.IActivityTaskManager;
+import android.app.PendingIntent;
+import android.app.SynchronousUserSwitchObserver;
+import android.app.TaskStackListener;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.IBiometricPromptReceiver;
+import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.fingerprint.Fingerprint;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IHwBinder;
+import android.os.IRemoteCallback;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Slog;
+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;
+import com.android.server.biometrics.fingerprint.FingerprintService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract base class containing all of the business logic for biometric services, e.g.
+ * Fingerprint, Face, Iris.
+ *
+ * @hide
+ */
+public abstract class BiometricServiceBase extends SystemService
+        implements IHwBinder.DeathRecipient {
+
+    protected static final boolean DEBUG = true;
+
+    private static final String KEY_LOCKOUT_RESET_USER = "lockout_reset_user";
+    private static final int MSG_USER_SWITCHING = 10;
+    private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30 * 1000;
+    private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
+
+    private final Context mContext;
+    private final String mKeyguardPackage;
+    private final SparseBooleanArray mTimedLockoutCleared;
+    private final SparseIntArray mFailedAttempts;
+    private final IActivityTaskManager mActivityTaskManager;
+    private final AlarmManager mAlarmManager;
+    private final PowerManager mPowerManager;
+    private final UserManager mUserManager;
+    private final MetricsLogger mMetricsLogger;
+    private final BiometricTaskStackListener mTaskStackListener = new BiometricTaskStackListener();
+    private final ResetClientStateRunnable mResetClientState = new ResetClientStateRunnable();
+    private final LockoutReceiver mLockoutReceiver = new LockoutReceiver();
+    private final ArrayList<LockoutResetMonitor> mLockoutMonitors = new ArrayList<>();
+
+    protected final IStatusBarService mStatusBarService;
+    protected final Map<Integer, Long> mAuthenticatorIds =
+            Collections.synchronizedMap(new HashMap<>());
+    protected final ResetFailedAttemptsForUserRunnable mResetFailedAttemptsForCurrentUserRunnable =
+            new ResetFailedAttemptsForUserRunnable();
+    protected final AppOpsManager mAppOps;
+    protected final H mHandler = new H();
+
+    private ClientMonitor mCurrentClient;
+    private ClientMonitor mPendingClient;
+    private PerformanceStats mPerformanceStats;
+    protected int mCurrentUserId = UserHandle.USER_NULL;
+    // Tracks if the current authentication makes use of CryptoObjects.
+    protected boolean mIsCrypto;
+    // Normal authentications are tracked by mPerformanceMap.
+    protected HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>();
+    // Transactions that make use of CryptoObjects are tracked by mCryptoPerformaceMap.
+    protected HashMap<Integer, PerformanceStats> mCryptoPerformanceMap = new HashMap<>();
+
+    protected class PerformanceStats {
+        public int accept; // number of accepted biometrics
+        public int reject; // number of rejected biometrics
+        public int acquire; // total number of acquisitions. Should be >= accept+reject due to poor
+        // image acquisition in some cases (too fast, too slow, dirty sensor, etc.)
+        public int lockout; // total number of lockouts
+        public int permanentLockout; // total number of permanent lockouts
+    }
+
+    /**
+     * @return the log tag.
+     */
+    protected abstract String getTag();
+
+    /**
+     * @return the biometric utilities for a specific implementation.
+     */
+    protected abstract BiometricUtils getBiometricUtils();
+
+    /**
+     * @return the number of failed attempts after which the user will be temporarily locked out
+     *         from using the biometric. A strong auth (pin/pattern/pass) clears this counter.
+     */
+    protected abstract int getFailedAttemptsLockoutTimed();
+
+    /**
+     * @return the number of failed attempts after which the user will be permanently locked out
+     *         from using the biometric. A strong auth (pin/pattern/pass) clears this counter.
+     */
+    protected abstract int getFailedAttemptsLockoutPermanent();
+
+    /**
+     * @return the metrics constants for a biometric implementation.
+     */
+    protected abstract Metrics getMetrics();
+
+    /**
+     * @param userId
+     * @return true if the enrollment limit has been reached.
+     */
+    protected abstract boolean hasReachedEnrollmentLimit(int userId);
+
+    /**
+     * Notifies the HAL that the user has changed.
+     * @param userId
+     * @param clientPackage
+     */
+    protected abstract void updateActiveGroup(int userId, String clientPackage);
+
+    /**
+     * @return The protected intent to reset lockout for a specific biometric.
+     */
+    protected abstract String getLockoutResetIntent();
+
+    /**
+     * @return The permission the sender is required to have in order for the lockout reset intent
+     *         to be received by the BiometricService implementation.
+     */
+    protected abstract String getLockoutBroadcastPermission();
+
+    /**
+     * @return The HAL ID.
+     */
+    protected abstract long getHalDeviceId();
+
+    /**
+     * This method is called when the user switches. Implementations should probably notify the
+     * HAL.
+     * @param userId
+     */
+    protected abstract void handleUserSwitching(int userId);
+
+    /**
+     * @param userId
+     * @return Returns true if the user has any enrolled biometrics.
+     */
+    protected abstract boolean hasEnrolledBiometrics(int userId);
+
+    /**
+     * @return Returns the MANAGE_* permission string, which is required for enrollment, removal
+     * etc.
+     */
+    protected abstract String getManageBiometricPermission();
+
+    /**
+     * Checks if the caller has permission to use the biometric service - throws a SecurityException
+     * if not.
+     */
+    protected abstract void checkUseBiometricPermission();
+
+    /**
+     * Checks if the caller passes the app ops check
+     */
+    protected abstract boolean checkAppOps(int uid, String opPackageName);
+
+    /**
+     * Notifies clients of any change in the biometric state (active / idle). This is mainly for
+     * Fingerprint navigation gestures.
+     * @param isActive
+     */
+    protected void notifyClientActiveCallbacks(boolean isActive) {}
+
+    protected abstract class AuthenticationClientImpl extends AuthenticationClient {
+
+        public AuthenticationClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
+                IBinder token, ServiceListener listener, int targetUserId, int groupId, long opId,
+                boolean restricted, String owner, Bundle bundle,
+                IBiometricPromptReceiver dialogReceiver,
+                IStatusBarService statusBarService, boolean requireConfirmation) {
+            super(context, getMetrics(), daemon, halDeviceId, token, listener,
+                    targetUserId, groupId, opId, restricted, owner, bundle, dialogReceiver,
+                    statusBarService, requireConfirmation);
+        }
+
+        @Override
+        public void onStart() {
+            try {
+                mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
+            } catch (RemoteException e) {
+                Slog.e(getTag(), "Could not register task stack listener", e);
+            }
+        }
+
+        @Override
+        public void onStop() {
+            try {
+                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+            } catch (RemoteException e) {
+                Slog.e(getTag(), "Could not unregister task stack listener", e);
+            }
+        }
+
+        @Override
+        public void resetFailedAttempts() {
+            resetFailedAttemptsForUser(true /* clearAttemptCounter */,
+                    ActivityManager.getCurrentUser());
+        }
+
+        @Override
+        public void notifyUserActivity() {
+            userActivity();
+        }
+
+        @Override
+        public int handleFailedAttempt() {
+            final int currentUser = ActivityManager.getCurrentUser();
+            mFailedAttempts.put(currentUser, mFailedAttempts.get(currentUser, 0) + 1);
+            mTimedLockoutCleared.put(ActivityManager.getCurrentUser(), false);
+            final int lockoutMode = getLockoutMode();
+            if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
+                mPerformanceStats.permanentLockout++;
+            } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
+                mPerformanceStats.lockout++;
+            }
+
+            // Failing multiple times will continue to push out the lockout time
+            if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
+                scheduleLockoutResetForUser(currentUser);
+                return lockoutMode;
+            }
+            return AuthenticationClient.LOCKOUT_NONE;
+        }
+
+        @Override
+        public void onAuthenticationConfirmed() {
+            removeClient(mCurrentClient);
+        }
+    }
+
+    protected class EnrollClientImpl extends EnrollClient {
+
+        public EnrollClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
+                IBinder token, ServiceListener listener, int userId, int groupId,
+                byte[] cryptoToken, boolean restricted, String owner) {
+            super(context, getMetrics(), daemon, halDeviceId, token, listener,
+                    userId, groupId, cryptoToken, restricted, owner, getBiometricUtils());
+        }
+
+        @Override
+        public void notifyUserActivity() {
+            userActivity();
+        }
+    }
+
+    protected class RemovalClientImpl extends RemovalClient {
+        private boolean mShouldNotify;
+
+        public RemovalClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
+                IBinder token, ServiceListener listener, int fingerId, int groupId, int userId,
+                boolean restricted, String owner) {
+            super(context, getMetrics(), daemon, halDeviceId, token, listener, fingerId, groupId,
+                    userId, restricted, owner, getBiometricUtils());
+        }
+
+        public void setShouldNotifyUserActivity(boolean shouldNotify) {
+            mShouldNotify = shouldNotify;
+        }
+
+        @Override
+        public void notifyUserActivity() {
+            if (mShouldNotify) {
+                userActivity();
+            }
+        }
+    }
+
+    protected class EnumerateClientImpl extends EnumerateClient {
+
+        public EnumerateClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
+                IBinder token, ServiceListener listener, int groupId, int userId,
+                boolean restricted, String owner) {
+            super(context, getMetrics(), daemon, halDeviceId, token, listener, groupId, userId,
+                    restricted, owner);
+        }
+
+        @Override
+        public void notifyUserActivity() {
+            userActivity();
+        }
+    }
+
+    /**
+     * Wraps the callback interface from Service -> Manager
+     */
+    protected interface ServiceListener {
+        default void onEnrollResult(BiometricAuthenticator.Identifier identifier,
+                int remaining) throws RemoteException {};
+
+        void onAcquired(long deviceId, int acquiredInfo, int vendorCode)
+                throws RemoteException;
+
+        void onAuthenticationSucceeded(long deviceId,
+                BiometricAuthenticator.Identifier biometric, int userId)
+                throws RemoteException;
+
+        void onAuthenticationFailed(long deviceId)
+                throws RemoteException;
+
+        void onError(long deviceId, int error, int vendorCode)
+                throws RemoteException;
+
+        default void onRemoved(BiometricAuthenticator.Identifier identifier,
+                int remaining) throws RemoteException {};
+
+        default void onEnumerated(BiometricAuthenticator.Identifier identifier,
+                int remaining) throws RemoteException {};
+    }
+
+    /**
+     * Wraps a portion of the interface from Service -> Daemon that is used by the ClientMonitor
+     * subclasses.
+     */
+    protected interface DaemonWrapper {
+        int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. see errno.h.
+        int authenticate(long operationId, int groupId) throws RemoteException;
+        int cancel() throws RemoteException;
+        int remove(int groupId, int biometricId) throws RemoteException;
+        int enumerate() throws RemoteException;
+        int enroll(byte[] cryptoToken, int groupId, int timeout) throws RemoteException;
+    }
+
+    /**
+     * Handler which all subclasses should post events to.
+     */
+    protected final class H extends Handler {
+        @Override
+        public void handleMessage(android.os.Message msg) {
+            switch (msg.what) {
+                case MSG_USER_SWITCHING:
+                    handleUserSwitching(msg.arg1);
+                    break;
+
+                default:
+                    Slog.w(getTag(), "Unknown message:" + msg.what);
+            }
+        }
+    }
+
+    private final class BiometricTaskStackListener extends TaskStackListener {
+        @Override
+        public void onTaskStackChanged() {
+            try {
+                if (!(mCurrentClient instanceof AuthenticationClient)) {
+                    return;
+                }
+                final String currentClient = mCurrentClient.getOwnerString();
+                if (isKeyguard(currentClient)) {
+                    return; // Keyguard is always allowed
+                }
+                List<ActivityManager.RunningTaskInfo> runningTasks =
+                        mActivityTaskManager.getTasks(1);
+                if (!runningTasks.isEmpty()) {
+                    final String topPackage = runningTasks.get(0).topActivity.getPackageName();
+                    if (!topPackage.contentEquals(currentClient)
+                            && !mCurrentClient.isAlreadyDone()) {
+                        Slog.e(getTag(), "Stopping background authentication, top: " + topPackage
+                                + " currentClient: " + currentClient);
+                        mCurrentClient.stop(false /* initiatedByClient */);
+                    }
+                }
+            } catch (RemoteException e) {
+                Slog.e(getTag(), "Unable to get running tasks", e);
+            }
+        }
+    }
+
+    private final class ResetClientStateRunnable implements Runnable {
+        @Override
+        public void run() {
+            /**
+             * Warning: if we get here, the driver never confirmed our call to cancel the current
+             * operation (authenticate, enroll, remove, enumerate, etc), which is
+             * really bad.  The result will be a 3-second delay in starting each new client.
+             * If you see this on a device, make certain the driver notifies with
+             * {@link BiometricConstants#BIOMETRIC_ERROR_CANCELED} in response to cancel()
+             * once it has successfully switched to the IDLE state in the HAL.
+             * Additionally,{@link BiometricConstants#BIOMETRIC_ERROR_CANCELED} should only be sent
+             * in response to an actual cancel() call.
+             */
+            Slog.w(getTag(), "Client "
+                    + (mCurrentClient != null ? mCurrentClient.getOwnerString() : "null")
+                    + " failed to respond to cancel, starting client "
+                    + (mPendingClient != null ? mPendingClient.getOwnerString() : "null"));
+
+            mCurrentClient = null;
+            startClient(mPendingClient, false);
+        }
+    }
+
+    private final class LockoutReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Slog.v(getTag(), "Resetting lockout: " + intent.getAction());
+            if (getLockoutResetIntent().equals(intent.getAction())) {
+                final int user = intent.getIntExtra(KEY_LOCKOUT_RESET_USER, 0);
+                resetFailedAttemptsForUser(false /* clearAttemptCounter */, user);
+            }
+        }
+    }
+
+    private final class ResetFailedAttemptsForUserRunnable implements Runnable {
+        @Override
+        public void run() {
+            resetFailedAttemptsForUser(true /* clearAttemptCounter */,
+                    ActivityManager.getCurrentUser());
+        }
+    }
+
+    private final class LockoutResetMonitor implements IBinder.DeathRecipient {
+        private static final long WAKELOCK_TIMEOUT_MS = 2000;
+        private final IBiometricServiceLockoutResetCallback mCallback;
+        private final PowerManager.WakeLock mWakeLock;
+
+        public LockoutResetMonitor(IBiometricServiceLockoutResetCallback callback) {
+            mCallback = callback;
+            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    "lockout reset callback");
+            try {
+                mCallback.asBinder().linkToDeath(LockoutResetMonitor.this, 0);
+            } catch (RemoteException e) {
+                Slog.w(getTag(), "caught remote exception in linkToDeath", e);
+            }
+        }
+
+        public void sendLockoutReset() {
+            if (mCallback != null) {
+                try {
+                    mWakeLock.acquire(WAKELOCK_TIMEOUT_MS);
+                    mCallback.onLockoutReset(getHalDeviceId(), new IRemoteCallback.Stub() {
+                        @Override
+                        public void sendResult(Bundle data) throws RemoteException {
+                            releaseWakelock();
+                        }
+                    });
+                } catch (DeadObjectException e) {
+                    Slog.w(getTag(), "Death object while invoking onLockoutReset: ", e);
+                    mHandler.post(mRemoveCallbackRunnable);
+                } catch (RemoteException e) {
+                    Slog.w(getTag(), "Failed to invoke onLockoutReset: ", e);
+                    releaseWakelock();
+                }
+            }
+        }
+
+        private final Runnable mRemoveCallbackRunnable = new Runnable() {
+            @Override
+            public void run() {
+                releaseWakelock();
+                removeLockoutResetCallback(LockoutResetMonitor.this);
+            }
+        };
+
+        @Override
+        public void binderDied() {
+            Slog.e(getTag(), "Lockout reset callback binder died");
+            mHandler.post(mRemoveCallbackRunnable);
+        }
+
+        private void releaseWakelock() {
+            if (mWakeLock.isHeld()) {
+                mWakeLock.release();
+            }
+        }
+    }
+
+    /**
+     * Initializes the system service.
+     * <p>
+     * Subclasses must define a single argument constructor that accepts the context
+     * and passes it to super.
+     * </p>
+     *
+     * @param context The system server context.
+     */
+    public BiometricServiceBase(Context context) {
+        super(context);
+        mContext = context;
+        mStatusBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
+                com.android.internal.R.string.config_keyguardComponent)).getPackageName();
+        mAppOps = context.getSystemService(AppOpsManager.class);
+        mTimedLockoutCleared = new SparseBooleanArray();
+        mFailedAttempts = new SparseIntArray();
+        mActivityTaskManager = ((ActivityTaskManager) context.getSystemService(
+                Context.ACTIVITY_TASK_SERVICE)).getService();
+        mPowerManager = mContext.getSystemService(PowerManager.class);
+        mAlarmManager = mContext.getSystemService(AlarmManager.class);
+        mUserManager = UserManager.get(mContext);
+        mMetricsLogger = new MetricsLogger();
+        mContext.registerReceiver(mLockoutReceiver, new IntentFilter(getLockoutResetIntent()),
+                getLockoutBroadcastPermission(), null /* handler */);
+    }
+
+    @Override
+    public void onStart() {
+        listenForUserSwitches();
+    }
+
+    @Override
+    public void serviceDied(long cookie) {
+        Slog.e(getTag(), "HAL died");
+        mMetricsLogger.count(getMetrics().tagHalDied(), 1);
+        handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                0 /*vendorCode */);
+    }
+
+    protected ClientMonitor getCurrentClient() {
+        return mCurrentClient;
+    }
+
+    protected ClientMonitor getPendingClient() {
+        return mPendingClient;
+    }
+
+    /**
+     * Callback handlers from the daemon. The caller must put this on a handler.
+     */
+
+    protected void handleAcquired(long deviceId, int acquiredInfo, int vendorCode) {
+        ClientMonitor client = mCurrentClient;
+        if (client != null && client.onAcquired(acquiredInfo, vendorCode)) {
+            removeClient(client);
+        }
+        if (mPerformanceStats != null && getLockoutMode() == AuthenticationClient.LOCKOUT_NONE
+                && client instanceof AuthenticationClient) {
+            // ignore enrollment acquisitions or acquisitions when we're locked out
+            mPerformanceStats.acquire++;
+        }
+    }
+
+    protected void handleAuthenticated(BiometricAuthenticator.Identifier identifier,
+            ArrayList<Byte> token) {
+        ClientMonitor client = mCurrentClient;
+        final boolean authenticated = identifier.getBiometricId() != 0;
+
+        if (client != null && client.onAuthenticated(identifier, authenticated, token)) {
+            removeClient(client);
+        }
+        if (authenticated) {
+            mPerformanceStats.accept++;
+        } else {
+            mPerformanceStats.reject++;
+        }
+    }
+
+    protected void handleEnrollResult(BiometricAuthenticator.Identifier identifier,
+            int remaining) {
+        ClientMonitor client = mCurrentClient;
+        if (client != null && client.onEnrollResult(identifier, remaining)) {
+            removeClient(client);
+            // When enrollment finishes, update this group's authenticator id, as the HAL has
+            // already generated a new authenticator id when the new biometric is enrolled.
+            if (identifier instanceof Fingerprint) {
+                updateActiveGroup(((Fingerprint)identifier).getGroupId(), null);
+            } else {
+                updateActiveGroup(mCurrentUserId, null);
+            }
+
+        }
+    }
+
+    protected void handleError(long deviceId, int error, int vendorCode) {
+        final ClientMonitor client = mCurrentClient;
+
+        if (DEBUG) Slog.v(getTag(), "handleError(client="
+                + (client != null ? client.getOwnerString() : "null") + ", error = " + error + ")");
+
+        if (client != null && client.onError(deviceId, error, vendorCode)) {
+            removeClient(client);
+        }
+
+        if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
+            mHandler.removeCallbacks(mResetClientState);
+            if (mPendingClient != null) {
+                if (DEBUG) Slog.v(getTag(), "start pending client " +
+                        mPendingClient.getOwnerString());
+                startClient(mPendingClient, false);
+                mPendingClient = null;
+            }
+        }
+    }
+
+    protected void handleRemoved(BiometricAuthenticator.Identifier identifier,
+            final int remaining) {
+        if (DEBUG) Slog.w(getTag(), "Removed: fid=" + identifier.getBiometricId()
+                + ", dev=" + identifier.getDeviceId()
+                + ", rem=" + remaining);
+
+        ClientMonitor client = mCurrentClient;
+        if (client != null && client.onRemoved(identifier, remaining)) {
+            removeClient(client);
+            // When the last biometric of a group is removed, update the authenticator id
+            int userId = mCurrentUserId;
+            if (identifier instanceof Fingerprint) {
+                userId = ((Fingerprint) identifier).getGroupId();
+            }
+            if (!hasEnrolledBiometrics(userId)) {
+                updateActiveGroup(userId, null);
+            }
+        }
+    }
+
+    /**
+     * Calls from the Manager. These are still on the calling binder's thread.
+     */
+
+    protected void enrollInternal(EnrollClientImpl client, int userId) {
+        if (hasReachedEnrollmentLimit(userId)) {
+            return;
+        }
+
+        // Group ID is arbitrarily set to parent profile user ID. It just represents
+        // the default biometrics for the user.
+        if (!isCurrentUserOrProfile(userId)) {
+            return;
+        }
+
+        mHandler.post(() -> {
+            startClient(client, true /* initiatedByClient */);
+        });
+    }
+
+    protected void cancelEnrollmentInternal(IBinder token) {
+        mHandler.post(() -> {
+            ClientMonitor client = mCurrentClient;
+            if (client instanceof EnrollClient && client.getToken() == token) {
+                client.stop(client.getToken() == token);
+            }
+        });
+    }
+
+    protected void authenticateInternal(AuthenticationClientImpl client, long opId,
+            String opPackageName) {
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final int callingUserId = UserHandle.getCallingUserId();
+        authenticateInternal(client, opId, opPackageName, callingUid, callingPid, callingUserId);
+    }
+
+    protected void authenticateInternal(AuthenticationClientImpl client, long opId,
+            String opPackageName, int callingUid, int callingPid, int callingUserId) {
+        if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
+                callingUserId)) {
+            if (DEBUG) Slog.v(getTag(), "authenticate(): reject " + opPackageName);
+            return;
+        }
+
+        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.
+            HashMap<Integer, PerformanceStats> pmap
+                    = (opId == 0) ? mPerformanceMap : mCryptoPerformanceMap;
+            PerformanceStats stats = pmap.get(mCurrentUserId);
+            if (stats == null) {
+                stats = new PerformanceStats();
+                pmap.put(mCurrentUserId, stats);
+            }
+            mPerformanceStats = stats;
+            mIsCrypto = (opId != 0);
+
+            startAuthentication(client, opPackageName);
+        });
+    }
+
+    protected void cancelAuthenticationInternal(final IBinder token, final String opPackageName) {
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final int callingUserId = UserHandle.getCallingUserId();
+        cancelAuthenticationInternal(token, opPackageName, callingUid, callingPid, callingUserId);
+    }
+
+    protected void cancelAuthenticationInternal(final IBinder token, final String opPackageName,
+            int callingUid, int callingPid, int callingUserId) {
+        if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
+                callingUserId)) {
+            if (DEBUG) Slog.v(getTag(), "cancelAuthentication(): reject " + opPackageName);
+            return;
+        }
+
+        mHandler.post(() -> {
+            ClientMonitor client = mCurrentClient;
+            if (client instanceof AuthenticationClient) {
+                if (client.getToken() == token) {
+                    if (DEBUG) Slog.v(getTag(), "stop client " + client.getOwnerString());
+                    client.stop(client.getToken() == token);
+                } else {
+                    if (DEBUG) Slog.v(getTag(), "can't stop client "
+                            + client.getOwnerString() + " since tokens don't match");
+                }
+            } else if (client != null) {
+                if (DEBUG) Slog.v(getTag(), "can't cancel non-authenticating client "
+                        + client.getOwnerString());
+            }
+        });
+    }
+
+    protected void setActiveUserInternal(int userId) {
+        mHandler.post(() -> {
+            updateActiveGroup(userId, null /* clientPackage */);
+        });
+    }
+
+    protected void removeInternal(RemovalClientImpl client) {
+        mHandler.post(() -> {
+            startClient(client, true /* initiatedByClient */);
+        });
+    }
+
+    protected void enumerateInternal(EnumerateClientImpl client) {
+        mHandler.post(() -> {
+            startClient(client, true /* initiatedByClient */);
+        });
+    }
+
+    // Should be done on a handler thread - not on the Binder's thread.
+    private void startAuthentication(AuthenticationClientImpl client, String opPackageName) {
+        updateActiveGroup(client.getGroupId(), opPackageName);
+
+        if (DEBUG) Slog.v(getTag(), "startAuthentication(" + opPackageName + ")");
+
+        int lockoutMode = getLockoutMode();
+        if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
+            Slog.v(getTag(), "In lockout mode(" + lockoutMode +
+                    ") ; disallowing authentication");
+            int errorCode = lockoutMode == AuthenticationClient.LOCKOUT_TIMED ?
+                    BiometricConstants.BIOMETRIC_ERROR_LOCKOUT :
+                    BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
+            if (!client.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */)) {
+                Slog.w(getTag(), "Cannot send permanent lockout message to client");
+            }
+            return;
+        }
+        startClient(client, true /* initiatedByClient */);
+    }
+
+    protected void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback) {
+        mHandler.post(() -> {
+           final LockoutResetMonitor monitor = new LockoutResetMonitor(callback);
+           if (!mLockoutMonitors.contains(monitor)) {
+               mLockoutMonitors.add(monitor);
+           }
+        });
+    }
+
+    /**
+     * Helper methods.
+     */
+
+    /**
+     * @param opPackageName name of package for caller
+     * @param requireForeground only allow this call while app is in the foreground
+     * @return true if caller can use the biometric API
+     */
+    protected boolean canUseBiometric(String opPackageName, boolean requireForeground, int uid,
+            int pid, int userId) {
+        checkUseBiometricPermission();
+
+        if (isKeyguard(opPackageName)) {
+            return true; // Keyguard is always allowed
+        }
+        if (!isCurrentUserOrProfile(userId)) {
+            Slog.w(getTag(), "Rejecting " + opPackageName + "; not a current user or profile");
+            return false;
+        }
+        if (!checkAppOps(uid, opPackageName)) {
+            Slog.w(getTag(), "Rejecting " + opPackageName + "; permission denied");
+            return false;
+        }
+
+        if (requireForeground && !(isForegroundActivity(uid, pid) || isCurrentClient(
+                opPackageName))) {
+            Slog.w(getTag(), "Rejecting " + opPackageName + "; not in foreground");
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @param opPackageName package of the caller
+     * @return true if this is the same client currently using the biometric
+     */
+    private boolean isCurrentClient(String opPackageName) {
+        return mCurrentClient != null && mCurrentClient.getOwnerString().equals(opPackageName);
+    }
+
+    /**
+     * @return true if this is keyguard package
+     */
+    private boolean isKeyguard(String clientPackage) {
+        return mKeyguardPackage.equals(clientPackage);
+    }
+
+    protected int getLockoutMode() {
+        final int currentUser = ActivityManager.getCurrentUser();
+        final int failedAttempts = mFailedAttempts.get(currentUser, 0);
+        if (failedAttempts >= getFailedAttemptsLockoutPermanent()) {
+            return AuthenticationClient.LOCKOUT_PERMANENT;
+        } else if (failedAttempts > 0 &&
+                mTimedLockoutCleared.get(currentUser, false) == false
+                && (failedAttempts % getFailedAttemptsLockoutTimed() == 0)) {
+            return AuthenticationClient.LOCKOUT_TIMED;
+        }
+        return AuthenticationClient.LOCKOUT_NONE;
+    }
+
+    private boolean isForegroundActivity(int uid, int pid) {
+        try {
+            List<ActivityManager.RunningAppProcessInfo> procs =
+                    ActivityManager.getService().getRunningAppProcesses();
+            int N = procs.size();
+            for (int i = 0; i < N; i++) {
+                ActivityManager.RunningAppProcessInfo proc = procs.get(i);
+                if (proc.pid == pid && proc.uid == uid
+                        && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) {
+                    return true;
+                }
+            }
+        } catch (RemoteException e) {
+            Slog.w(getTag(), "am.getRunningAppProcesses() failed");
+        }
+        return false;
+    }
+
+    /**
+     * Calls the HAL to switch states to the new task. If there's already a current task,
+     * it calls cancel() and sets mPendingClient to begin when the current task finishes
+     * ({@link BiometricConstants#BIOMETRIC_ERROR_CANCELED}).
+     *
+     * @param newClient the new client that wants to connect
+     * @param initiatedByClient true for authenticate, remove and enroll
+     */
+    private void startClient(ClientMonitor newClient, boolean initiatedByClient) {
+        ClientMonitor currentClient = mCurrentClient;
+        if (currentClient != null) {
+            if (DEBUG) Slog.v(getTag(), "request stop current client " +
+                    currentClient.getOwnerString());
+
+            // This check only matters for FingerprintService, since enumerate may call back
+            // multiple times.
+            if (currentClient instanceof FingerprintService.EnumerateClientImpl ||
+                    currentClient instanceof FingerprintService.RemovalClientImpl) {
+                // This condition means we're currently running internal diagnostics to
+                // remove extra fingerprints in the hardware and/or the software
+                // TODO: design an escape hatch in case client never finishes
+                if (newClient != null) {
+                    Slog.w(getTag(), "Internal cleanup in progress but trying to start client "
+                            + newClient.getClass().getSuperclass().getSimpleName()
+                            + "(" + newClient.getOwnerString() + ")"
+                            + ", initiatedByClient = " + initiatedByClient);
+                }
+            } else {
+                currentClient.stop(initiatedByClient);
+            }
+            mPendingClient = newClient;
+            mHandler.removeCallbacks(mResetClientState);
+            mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
+        } else if (newClient != null) {
+            mCurrentClient = newClient;
+            if (DEBUG) Slog.v(getTag(), "starting client "
+                    + newClient.getClass().getSuperclass().getSimpleName()
+                    + "(" + newClient.getOwnerString() + ")"
+                    + ", initiatedByClient = " + initiatedByClient);
+            notifyClientActiveCallbacks(true);
+
+            newClient.start();
+        }
+    }
+
+    protected void removeClient(ClientMonitor client) {
+        if (client != null) {
+            client.destroy();
+            if (client != mCurrentClient && mCurrentClient != null) {
+                Slog.w(getTag(), "Unexpected client: " + client.getOwnerString() + "expected: "
+                        + mCurrentClient.getOwnerString());
+            }
+        }
+        if (mCurrentClient != null) {
+            if (DEBUG) Slog.v(getTag(), "Done with client: " + client.getOwnerString());
+            mCurrentClient = null;
+        }
+        if (mPendingClient == null) {
+            notifyClientActiveCallbacks(false);
+        }
+    }
+
+    /**
+     * Populates existing authenticator ids. To be used only during the start of the service.
+     */
+    protected void loadAuthenticatorIds() {
+        // This operation can be expensive, so keep track of the elapsed time. Might need to move to
+        // background if it takes too long.
+        long t = System.currentTimeMillis();
+        mAuthenticatorIds.clear();
+        for (UserInfo user : UserManager.get(getContext()).getUsers(true /* excludeDying */)) {
+            int userId = getUserOrWorkProfileId(null, user.id);
+            if (!mAuthenticatorIds.containsKey(userId)) {
+                updateActiveGroup(userId, null);
+            }
+        }
+
+        t = System.currentTimeMillis() - t;
+        if (t > 1000) {
+            Slog.w(getTag(), "loadAuthenticatorIds() taking too long: " + t + "ms");
+        }
+    }
+
+    /**
+     * @param clientPackage the package of the caller
+     * @return the profile id
+     */
+    protected int getUserOrWorkProfileId(String clientPackage, int userId) {
+        if (!isKeyguard(clientPackage) && isWorkProfile(userId)) {
+            return userId;
+        }
+        return getEffectiveUserId(userId);
+    }
+
+    protected boolean isRestricted() {
+        // Only give privileged apps (like Settings) access to biometric info
+        final boolean restricted = !hasPermission(getManageBiometricPermission());
+        return restricted;
+    }
+
+    protected boolean hasPermission(String permission) {
+        return getContext().checkCallingOrSelfPermission(permission)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
+    protected void checkPermission(String permission) {
+        getContext().enforceCallingOrSelfPermission(permission,
+                "Must have " + permission + " permission.");
+    }
+
+    protected boolean isCurrentUserOrProfile(int userId) {
+        UserManager um = UserManager.get(mContext);
+        if (um == null) {
+            Slog.e(getTag(), "Unable to acquire UserManager");
+            return false;
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            // Allow current user or profiles of the current user...
+            for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
+                if (profileId == userId) {
+                    return true;
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        return false;
+    }
+
+    /***
+     * @param opPackageName the name of the calling package
+     * @return authenticator id for the calling user
+     */
+    protected long getAuthenticatorId(String opPackageName) {
+        final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId());
+        return mAuthenticatorIds.getOrDefault(userId, 0L);
+    }
+
+    private void scheduleLockoutResetForUser(int userId) {
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                SystemClock.elapsedRealtime() + FAIL_LOCKOUT_TIMEOUT_MS,
+                getLockoutResetIntentForUser(userId));
+    }
+
+    private PendingIntent getLockoutResetIntentForUser(int userId) {
+        return PendingIntent.getBroadcast(mContext, userId,
+                new Intent(getLockoutResetIntent()).putExtra(KEY_LOCKOUT_RESET_USER, userId),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    private void userActivity() {
+        long now = SystemClock.uptimeMillis();
+        mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
+    }
+
+    /**
+     * @param userId
+     * @return true if this is a work profile
+     */
+    private boolean isWorkProfile(int userId) {
+        UserInfo userInfo = null;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            userInfo = mUserManager.getUserInfo(userId);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return userInfo != null && userInfo.isManagedProfile();
+    }
+
+
+    private int getEffectiveUserId(int userId) {
+        UserManager um = UserManager.get(mContext);
+        if (um != null) {
+            final long callingIdentity = Binder.clearCallingIdentity();
+            userId = um.getCredentialOwnerProfile(userId);
+            Binder.restoreCallingIdentity(callingIdentity);
+        } else {
+            Slog.e(getTag(), "Unable to acquire UserManager");
+        }
+        return userId;
+    }
+
+    // Attempt counter should only be cleared when Keyguard goes away or when
+    // a biometric is successfully authenticated.
+    private void resetFailedAttemptsForUser(boolean clearAttemptCounter, int userId) {
+        if (DEBUG && getLockoutMode() != AuthenticationClient.LOCKOUT_NONE) {
+            Slog.v(getTag(), "Reset biometric lockout, clearAttemptCounter=" + clearAttemptCounter);
+        }
+        if (clearAttemptCounter) {
+            mFailedAttempts.put(userId, 0);
+        }
+        mTimedLockoutCleared.put(userId, true);
+        // If we're asked to reset failed attempts externally (i.e. from Keyguard),
+        // the alarm might still be pending; remove it.
+        cancelLockoutResetForUser(userId);
+        notifyLockoutResetMonitors();
+    }
+
+    private void cancelLockoutResetForUser(int userId) {
+        mAlarmManager.cancel(getLockoutResetIntentForUser(userId));
+    }
+
+    private void listenForUserSwitches() {
+        try {
+            ActivityManager.getService().registerUserSwitchObserver(
+                    new SynchronousUserSwitchObserver() {
+                        @Override
+                        public void onUserSwitching(int newUserId) throws RemoteException {
+                            mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
+                                    .sendToTarget();
+                        }
+                    }, getTag());
+        } catch (RemoteException e) {
+            Slog.w(getTag(), "Failed to listen for user switching event" ,e);
+        }
+    }
+
+    private void notifyLockoutResetMonitors() {
+        for (int i = 0; i < mLockoutMonitors.size(); i++) {
+            mLockoutMonitors.get(i).sendLockoutReset();
+        }
+    }
+
+    private void removeLockoutResetCallback(
+            LockoutResetMonitor monitor) {
+        mLockoutMonitors.remove(monitor);
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index d30bed2..22b7418 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -28,6 +28,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 
+import java.util.ArrayList;
 import java.util.NoSuchElementException;
 
 /**
@@ -37,7 +38,7 @@
  */
 public abstract class ClientMonitor implements IBinder.DeathRecipient {
     protected static final int ERROR_ESRCH = 3; // Likely HAL is dead. See errno.h.
-    protected static final boolean DEBUG = BiometricService.DEBUG;
+    protected static final boolean DEBUG = BiometricServiceBase.DEBUG;
     private static final AudioAttributes FINGERPRINT_SONFICATION_ATTRIBUTES =
             new AudioAttributes.Builder()
                     .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
@@ -53,15 +54,16 @@
     private final String mOwner;
     private final VibrationEffect mSuccessVibrationEffect;
     private final VibrationEffect mErrorVibrationEffect;
-    private final BiometricService.DaemonWrapper mDaemon;
+    private final BiometricServiceBase.DaemonWrapper mDaemon;
 
     private IBinder mToken;
-    private BiometricService.ServiceListener mListener;
+    private BiometricServiceBase.ServiceListener mListener;
 
     protected final MetricsLogger mMetricsLogger;
     protected final Metrics mMetrics;
 
     protected boolean mAlreadyCancelled;
+    protected boolean mAlreadyDone;
 
     /**
      * @param context context of BiometricService
@@ -75,9 +77,10 @@
      * permission
      * @param owner name of the client that owns this
      */
-    public ClientMonitor(Context context, Metrics metrics, BiometricService.DaemonWrapper daemon,
-            long halDeviceId, IBinder token, BiometricService.ServiceListener listener, int userId,
-            int groupId, boolean restricted, String owner) {
+    public ClientMonitor(Context context, Metrics metrics,
+            BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
+            BiometricServiceBase.ServiceListener listener, int userId, int groupId,
+            boolean restricted, String owner) {
         mContext = context;
         mMetrics = metrics;
         mDaemon = daemon;
@@ -128,12 +131,17 @@
     public abstract boolean onEnrollResult(BiometricAuthenticator.Identifier identifier,
             int remaining);
     public abstract boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated);
+            boolean authenticated, ArrayList<Byte> token);
     public abstract boolean onRemoved(BiometricAuthenticator.Identifier identifier,
             int remaining);
     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.
@@ -220,11 +228,11 @@
         return mOwner;
     }
 
-    public final BiometricService.ServiceListener getListener() {
+    public final BiometricServiceBase.ServiceListener getListener() {
         return mListener;
     }
 
-    public final BiometricService.DaemonWrapper getDaemonWrapper() {
+    public final BiometricServiceBase.DaemonWrapper getDaemonWrapper() {
         return mDaemon;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/EnrollClient.java b/services/core/java/com/android/server/biometrics/EnrollClient.java
index c305eca6..76dc5a9 100644
--- a/services/core/java/com/android/server/biometrics/EnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/EnrollClient.java
@@ -23,6 +23,7 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
@@ -34,10 +35,10 @@
     private final byte[] mCryptoToken;
     private final BiometricUtils mBiometricUtils;
 
-    public EnrollClient(Context context, Metrics metrics, BiometricService.DaemonWrapper daemon,
-            long halDeviceId, IBinder token, BiometricService.ServiceListener listener, int userId,
-            int groupId, byte[] cryptoToken, boolean restricted, String owner,
-            BiometricUtils utils) {
+    public EnrollClient(Context context, Metrics metrics,
+            BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
+            BiometricServiceBase.ServiceListener listener, int userId, int groupId,
+            byte[] cryptoToken, boolean restricted, String owner, BiometricUtils utils) {
         super(context, metrics, daemon, halDeviceId, token, listener, userId, groupId, restricted,
                 owner);
         mBiometricUtils = utils;
@@ -126,7 +127,7 @@
 
     @Override
     public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated) {
+            boolean authenticated, ArrayList<Byte> token) {
         if (DEBUG) Slog.w(getLogTag(), "onAuthenticated() called for enroll!");
         return true; // Invalid for EnrollClient
     }
diff --git a/services/core/java/com/android/server/biometrics/EnumerateClient.java b/services/core/java/com/android/server/biometrics/EnumerateClient.java
index b763769..47dc7ff 100644
--- a/services/core/java/com/android/server/biometrics/EnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/EnumerateClient.java
@@ -23,13 +23,16 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import java.util.ArrayList;
+
 /**
  * A class to keep track of the enumeration state for a given client.
  */
 public abstract class EnumerateClient extends ClientMonitor {
-    public EnumerateClient(Context context, Metrics metrics, BiometricService.DaemonWrapper daemon,
-            long halDeviceId, IBinder token, BiometricService.ServiceListener listener, int groupId,
-            int userId, boolean restricted, String owner) {
+    public EnumerateClient(Context context, Metrics metrics,
+            BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
+            BiometricServiceBase.ServiceListener listener, int groupId, int userId,
+            boolean restricted, String owner) {
         super(context, metrics, daemon, halDeviceId, token, listener, userId, groupId, restricted,
                 owner);
     }
@@ -94,7 +97,7 @@
 
     @Override
     public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated) {
+            boolean authenticated, ArrayList<Byte> token) {
         if (DEBUG) Slog.w(getLogTag(), "onAuthenticated() called for enumerate!");
         return true; // Invalid for Enumerate.
     }
diff --git a/services/core/java/com/android/server/biometrics/RemovalClient.java b/services/core/java/com/android/server/biometrics/RemovalClient.java
index 3bf7f04..15b3773 100644
--- a/services/core/java/com/android/server/biometrics/RemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/RemovalClient.java
@@ -23,6 +23,8 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import java.util.ArrayList;
+
 /**
  * A class to keep track of the remove state for a given client.
  */
@@ -30,10 +32,10 @@
     private final int mBiometricId;
     private final BiometricUtils mBiometricUtils;
 
-    public RemovalClient(Context context, Metrics metrics, BiometricService.DaemonWrapper daemon,
-            long halDeviceId, IBinder token, BiometricService.ServiceListener listener,
-            int biometricId, int groupId, int userId, boolean restricted, String owner,
-            BiometricUtils utils) {
+    public RemovalClient(Context context, Metrics metrics,
+            BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
+            BiometricServiceBase.ServiceListener listener, int biometricId, int groupId, int userId,
+            boolean restricted, String owner, BiometricUtils utils) {
         super(context, metrics, daemon, halDeviceId, token, listener, userId, groupId, restricted,
                 owner);
         mBiometricId = biometricId;
@@ -111,7 +113,7 @@
 
     @Override
     public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated) {
+            boolean authenticated, ArrayList<Byte> token) {
         if (DEBUG) Slog.w(getLogTag(), "onAuthenticated() called for remove!");
         return true; // Invalid for Remove.
     }
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 660710e..f6af52a 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -28,10 +28,11 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.IBiometricPromptReceiver;
-import android.hardware.biometrics.IBiometricPromptServiceReceiver;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.biometrics.IBiometricServiceReceiver;
 import android.hardware.biometrics.face.V1_0.IBiometricsFace;
 import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
+import android.hardware.biometrics.face.V1_0.Status;
 import android.hardware.face.Face;
 import android.hardware.face.FaceManager;
 import android.hardware.face.IFaceService;
@@ -52,7 +53,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemServerInitThreadPool;
-import com.android.server.biometrics.BiometricService;
+import com.android.server.biometrics.BiometricServiceBase;
 import com.android.server.biometrics.BiometricUtils;
 import com.android.server.biometrics.Metrics;
 
@@ -73,7 +74,7 @@
  *
  * @hide
  */
-public class FaceService extends BiometricService {
+public class FaceService extends BiometricServiceBase {
 
     protected static final String TAG = "FaceService";
     private static final boolean DEBUG = true;
@@ -82,16 +83,18 @@
             "com.android.server.biometrics.face.ACTION_LOCKOUT_RESET";
     private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED = 3;
     private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT = 12;
+    private static final int CHALLENGE_TIMEOUT_SEC = 600; // 10 minutes
 
     private final class FaceAuthClient extends AuthenticationClientImpl {
         public FaceAuthClient(Context context,
                 DaemonWrapper daemon, long halDeviceId, IBinder token,
                 ServiceListener listener, int targetUserId, int groupId, long opId,
                 boolean restricted, String owner, Bundle bundle,
-                IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService) {
+                IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService,
+                boolean requireConfirmation) {
             super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
-                    restricted,
-                    owner, bundle, dialogReceiver, statusBarService);
+                    restricted, owner, bundle, dialogReceiver, statusBarService,
+                    requireConfirmation);
         }
 
         @Override
@@ -119,15 +122,15 @@
          * The following methods contain common code which is shared in biometrics/common.
          */
         @Override // Binder call
-        public long preEnroll(IBinder token) {
+        public long generateChallenge(IBinder token) {
             checkPermission(MANAGE_BIOMETRIC);
-            return startPreEnroll(token);
+            return startGenerateChallenge(token);
         }
 
         @Override // Binder call
-        public int postEnroll(IBinder token) {
+        public int revokeChallenge(IBinder token) {
             checkPermission(MANAGE_BIOMETRIC);
-            return startPostEnroll(token);
+            return startRevokeChallenge(token);
         }
 
         @Override // Binder call
@@ -159,15 +162,15 @@
             final AuthenticationClientImpl client = new FaceAuthClient(getContext(),
                     mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver),
                     mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName,
-                    null /* bundle */, null /* dialogReceiver */, mStatusBarService);
-
+                    null /* bundle */, null /* dialogReceiver */, mStatusBarService,
+                    false /* requireConfirmation */);
             authenticateInternal(client, opId, opPackageName);
         }
 
         @Override // Binder call
-        public void authenticateFromService(IBinder token, long opId, int groupId,
-                IBiometricPromptServiceReceiver receiver, int flags, String opPackageName,
-                Bundle bundle, IBiometricPromptReceiver dialogReceiver,
+        public void authenticateFromService(boolean requireConfirmation, IBinder token, long opId,
+                int groupId, IBiometricServiceReceiver receiver, int flags,
+                String opPackageName, Bundle bundle, IBiometricPromptReceiver dialogReceiver,
                 int callingUid, int callingPid, int callingUserId) {
             checkPermission(USE_BIOMETRIC_INTERNAL);
             final boolean restricted = true; // BiometricPrompt is always restricted
@@ -175,7 +178,7 @@
                     mDaemonWrapper, mHalDeviceId, token,
                     new BiometricPromptServiceListenerImpl(receiver),
                     mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName,
-                    bundle, dialogReceiver, mStatusBarService);
+                    bundle, dialogReceiver, mStatusBarService, true /* requireConfirmation */);
             authenticateInternal(client, opId, opPackageName, callingUid, callingPid,
                     callingUserId);
         }
@@ -344,6 +347,45 @@
             // TODO: confirm security token when we move timeout management into the HAL layer.
             mHandler.post(mResetFailedAttemptsForCurrentUserRunnable);
         }
+
+        @Override
+        public int setRequireAttention(boolean requireAttention, final byte[] token) {
+            checkPermission(MANAGE_BIOMETRIC);
+
+            final ArrayList<Byte> byteToken = new ArrayList<>();
+            for (int i = 0; i < token.length; i++) {
+                byteToken.add(token[i]);
+            }
+
+            int result;
+            try {
+                result = mDaemon != null ? mDaemon.setRequireAttention(requireAttention, byteToken)
+                        : Status.INTERNAL_ERROR;
+            } catch (RemoteException e) {
+                Slog.e(getTag(), "Unable to setRequireAttention to " + requireAttention);
+                result = Status.INTERNAL_ERROR;
+            }
+
+            return result;
+        }
+
+        @Override
+        public boolean getRequireAttention(final byte[] token) {
+            checkPermission(MANAGE_BIOMETRIC);
+
+            final ArrayList<Byte> byteToken = new ArrayList<>();
+            for (int i = 0; i < token.length; i++) {
+                byteToken.add(token[i]);
+            }
+
+            boolean result = true;
+            try {
+                result = mDaemon != null ? mDaemon.getRequireAttention(byteToken).value : true;
+            } catch (RemoteException e) {
+                Slog.e(getTag(), "Unable to getRequireAttention");
+            }
+            return result;
+        }
     }
 
     /**
@@ -352,10 +394,10 @@
      */
     private class BiometricPromptServiceListenerImpl implements ServiceListener {
 
-        private IBiometricPromptServiceReceiver mBiometricPromptServiceReceiver;
+        private IBiometricServiceReceiver mBiometricServiceReceiver;
 
-        public BiometricPromptServiceListenerImpl(IBiometricPromptServiceReceiver receiver) {
-            mBiometricPromptServiceReceiver = receiver;
+        public BiometricPromptServiceListenerImpl(IBiometricServiceReceiver receiver) {
+            mBiometricServiceReceiver = receiver;
         }
 
         @Override
@@ -364,8 +406,8 @@
             /**
              * Map the acquired codes onto existing {@link BiometricConstants} acquired codes.
              */
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onAcquired(deviceId,
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onAcquired(deviceId,
                         FaceManager.getMappedAcquiredInfo(acquiredInfo, vendorCode),
                         FaceManager.getAcquiredString(getContext(), acquiredInfo, vendorCode));
             }
@@ -374,22 +416,22 @@
         @Override
         public void onAuthenticationSucceeded(long deviceId,
                 BiometricAuthenticator.Identifier biometric, int userId) throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onAuthenticationSucceeded(deviceId);
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onAuthenticationSucceeded(deviceId);
             }
         }
 
         @Override
         public void onAuthenticationFailed(long deviceId) throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onAuthenticationFailed(deviceId);
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onAuthenticationFailed(deviceId);
             }
         }
 
         @Override
         public void onError(long deviceId, int error, int vendorCode) throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onError(deviceId, error,
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onError(deviceId, error,
                         FaceManager.getErrorString(getContext(), error, vendorCode));
             }
         }
@@ -729,8 +771,9 @@
     }
 
     @Override
-    protected int getAppOp() {
-        return AppOpsManager.OP_USE_FACE;
+    protected boolean checkAppOps(int uid, String opPackageName) {
+        return mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, opPackageName)
+                == AppOpsManager.MODE_ALLOWED;
     }
 
     @Override
@@ -776,30 +819,30 @@
         return mDaemon;
     }
 
-    private long startPreEnroll(IBinder token) {
+    private long startGenerateChallenge(IBinder token) {
         IBiometricsFace daemon = getFaceDaemon();
         if (daemon == null) {
-            Slog.w(TAG, "startPreEnroll: no face HAL!");
+            Slog.w(TAG, "startGenerateChallenge: no face HAL!");
             return 0;
         }
         try {
-            return daemon.generateChallenge().value;
+            return daemon.generateChallenge(CHALLENGE_TIMEOUT_SEC).value;
         } catch (RemoteException e) {
-            Slog.e(TAG, "startPreEnroll failed", e);
+            Slog.e(TAG, "startGenerateChallenge failed", e);
         }
         return 0;
     }
 
-    private int startPostEnroll(IBinder token) {
+    private int startRevokeChallenge(IBinder token) {
         IBiometricsFace daemon = getFaceDaemon();
         if (daemon == null) {
-            Slog.w(TAG, "startPostEnroll: no face HAL!");
+            Slog.w(TAG, "startRevokeChallenge: no face HAL!");
             return 0;
         }
         try {
             return daemon.revokeChallenge();
         } catch (RemoteException e) {
-            Slog.e(TAG, "startPostEnroll failed", e);
+            Slog.e(TAG, "startRevokeChallenge failed", e);
         }
         return 0;
     }
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 9f4fff8..b0b788f 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -31,7 +31,7 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.IBiometricPromptReceiver;
-import android.hardware.biometrics.IBiometricPromptServiceReceiver;
+import android.hardware.biometrics.IBiometricServiceReceiver;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;
@@ -59,7 +59,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.biometrics.AuthenticationClient;
-import com.android.server.biometrics.BiometricService;
+import com.android.server.biometrics.BiometricServiceBase;
 import com.android.server.biometrics.BiometricUtils;
 import com.android.server.biometrics.ClientMonitor;
 import com.android.server.biometrics.EnumerateClient;
@@ -84,7 +84,7 @@
  *
  * @hide
  */
-public class FingerprintService extends BiometricService {
+public class FingerprintService extends BiometricServiceBase {
 
     protected static final String TAG = "FingerprintService";
     private static final boolean DEBUG = true;
@@ -110,10 +110,11 @@
                 DaemonWrapper daemon, long halDeviceId, IBinder token,
                 ServiceListener listener, int targetUserId, int groupId, long opId,
                 boolean restricted, String owner, Bundle bundle,
-                IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService) {
+                IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService,
+                boolean requireConfirmation) {
             super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
-                    restricted,
-                    owner, bundle, dialogReceiver, statusBarService);
+                    restricted, owner, bundle, dialogReceiver, statusBarService,
+                    requireConfirmation);
         }
 
         @Override
@@ -182,14 +183,13 @@
             final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(),
                     mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver),
                     mCurrentUserId, groupId, opId, restricted, opPackageName, null /* bundle */,
-                    null /* dialogReceiver */, mStatusBarService);
-
+                    null /* dialogReceiver */, mStatusBarService, false /* requireConfirmation */);
             authenticateInternal(client, opId, opPackageName);
         }
 
         @Override // Binder call
         public void authenticateFromService(IBinder token, long opId, int groupId,
-                IBiometricPromptServiceReceiver receiver, int flags, String opPackageName,
+                IBiometricServiceReceiver receiver, int flags, String opPackageName,
                 Bundle bundle, IBiometricPromptReceiver dialogReceiver,
                 int callingUid, int callingPid, int callingUserId) {
             checkPermission(MANAGE_BIOMETRIC);
@@ -198,7 +198,7 @@
                     mDaemonWrapper, mHalDeviceId, token,
                     new BiometricPromptServiceListenerImpl(receiver),
                     mCurrentUserId, groupId, opId, restricted, opPackageName, bundle,
-                    dialogReceiver, mStatusBarService);
+                    dialogReceiver, mStatusBarService, false /* requireConfirmation */);
             authenticateInternal(client, opId, opPackageName, callingUid, callingPid,
                     callingUserId);
         }
@@ -390,17 +390,17 @@
      */
     private class BiometricPromptServiceListenerImpl implements ServiceListener {
 
-        private IBiometricPromptServiceReceiver mBiometricPromptServiceReceiver;
+        private IBiometricServiceReceiver mBiometricServiceReceiver;
 
-        public BiometricPromptServiceListenerImpl(IBiometricPromptServiceReceiver receiver) {
-            mBiometricPromptServiceReceiver = receiver;
+        public BiometricPromptServiceListenerImpl(IBiometricServiceReceiver receiver) {
+            mBiometricServiceReceiver = receiver;
         }
 
         @Override
         public void onAcquired(long deviceId, int acquiredInfo, int vendorCode)
                 throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onAcquired(deviceId, acquiredInfo,
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onAcquired(deviceId, acquiredInfo,
                         FingerprintManager.getAcquiredString(
                             getContext(), acquiredInfo, vendorCode));
             }
@@ -409,22 +409,22 @@
         @Override
         public void onAuthenticationSucceeded(long deviceId,
                 BiometricAuthenticator.Identifier biometric, int userId) throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onAuthenticationSucceeded(deviceId);
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onAuthenticationSucceeded(deviceId);
             }
         }
 
         @Override
         public void onAuthenticationFailed(long deviceId) throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onAuthenticationFailed(deviceId);
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onAuthenticationFailed(deviceId);
             }
         }
 
         @Override
         public void onError(long deviceId, int error, int vendorCode) throws RemoteException {
-            if (mBiometricPromptServiceReceiver != null) {
-                mBiometricPromptServiceReceiver.onError(deviceId, error,
+            if (mBiometricServiceReceiver != null) {
+                mBiometricServiceReceiver.onError(deviceId, error,
                         FingerprintManager.getErrorString(getContext(), error, vendorCode));
             }
         }
@@ -514,7 +514,7 @@
     /**
      * An internal class to help clean up unknown fingerprints in the hardware and software.
      */
-    private final class InternalEnumerateClient extends BiometricService.EnumerateClientImpl {
+    private final class InternalEnumerateClient extends BiometricServiceBase.EnumerateClientImpl {
 
         private List<Fingerprint> mEnrolledList;
         private List<Fingerprint> mUnknownFingerprints = new ArrayList<>(); // list of fp to delete
@@ -577,7 +577,7 @@
     /**
      * An internal class to help clean up unknown fingerprints in hardware and software.
      */
-    private final class InternalRemovalClient extends BiometricService.RemovalClientImpl {
+    private final class InternalRemovalClient extends BiometricServiceBase.RemovalClientImpl {
         public InternalRemovalClient(Context context,
                 DaemonWrapper daemon, long halDeviceId, IBinder token,
                 ServiceListener listener, int fingerId, int groupId, int userId, boolean restricted,
@@ -902,8 +902,16 @@
     }
 
     @Override
-    protected int getAppOp() {
-        return AppOpsManager.OP_USE_FINGERPRINT;
+    protected boolean checkAppOps(int uid, String opPackageName) {
+        boolean appOpsOk = false;
+        if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, opPackageName)
+                == AppOpsManager.MODE_ALLOWED) {
+            appOpsOk = true;
+        } else if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName)
+                == AppOpsManager.MODE_ALLOWED) {
+            appOpsOk = true;
+        }
+        return appOpsOk;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index c028a43..a769590 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -629,6 +629,11 @@
         if (mAppOps.noteOp(op, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
             return false;
         }
+        // Shell can access the clipboard for testing purposes.
+        if (mPm.checkPermission(android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND,
+                    callingPackage) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
         // The default IME is always allowed to access the clipboard.
         String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
                 Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.getUserId(callingUid));
@@ -639,12 +644,20 @@
             }
         }
 
-        // Otherwise only focused applications can access the clipboard.
-        boolean uidFocused = mWm.isUidFocused(callingUid);
-        if (!uidFocused) {
-            Slog.e(TAG, "Denying clipboard access to " + callingPackage
-                    + ", application is not in focus.");
+        switch (op) {
+            case AppOpsManager.OP_READ_CLIPBOARD:
+                // Clipboard can only be read by applications with focus.
+                boolean uidFocused = mWm.isUidFocused(callingUid);
+                if (!uidFocused) {
+                    Slog.e(TAG, "Denying clipboard access to " + callingPackage
+                            + ", application is not in focus.");
+                }
+                return uidFocused;
+            case AppOpsManager.OP_WRITE_CLIPBOARD:
+                // Writing is allowed without focus.
+                return true;
+            default:
+                throw new IllegalArgumentException("Unknown clipboard appop " + op);
         }
-        return uidFocused;
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index dc65e1e..b7bbd42 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -142,6 +142,35 @@
     }
 
     /**
+     * Read the global proxy settings and cache them in memory.
+     */
+    public 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) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
+                return;
+            }
+
+            synchronized (mProxyLock) {
+                mGlobalProxy = proxyProperties;
+            }
+        }
+        // TODO : shouldn't this function call mPacManager.setCurrentProxyScriptUrl ?
+    }
+
+    /**
      * 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
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 2a80f0e..48082b6 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -163,8 +163,8 @@
     // TODO: create separate trackers for each unique VPN to support
     // automated reconnection
 
-    private Context mContext;
-    private NetworkInfo mNetworkInfo;
+    private final Context mContext;
+    private final NetworkInfo mNetworkInfo;
     private String mPackage;
     private int mOwnerUID;
     private String mInterface;
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 2b1d919..1e6bb04 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -320,9 +320,8 @@
     }
 
     private static boolean getEnableLegacyDhcpServer(Context ctx) {
-        // TODO: make the default false (0) and update javadoc in Settings.java
         final ContentResolver cr = ctx.getContentResolver();
-        final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
+        final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
         return intVal != 0;
     }
 
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index d8d650b..5698fdf 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1226,7 +1226,7 @@
 
         if (userId == UserHandle.USER_ALL) {
             mContext.enforceCallingOrSelfPermission(
-                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, "No access to " + uri);
         } else if (userId < 0) {
             throw new IllegalArgumentException("Invalid user: " + userId);
         } else if (userId != UserHandle.getCallingUserId()) {
@@ -1247,7 +1247,7 @@
                             ? (Manifest.permission.INTERACT_ACROSS_USERS_FULL + " or " +
                                     Manifest.permission.INTERACT_ACROSS_USERS)
                             : Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-                    throw new SecurityException(TAG + "Neither user " + uid
+                    throw new SecurityException("No access to " + uri + ": neither user " + uid
                             + " nor current process has " + permissions);
                 }
             }
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/SystemAudioInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
index d4932f9..2fdcb51 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
@@ -25,6 +25,9 @@
 
     // State that waits for <Active Source> once send <Request Active Source>.
     private static final int STATE_WAITING_FOR_ACTIVE_SOURCE = 1;
+    // State that waits for TV supporting Audio System Mode or not
+    // once received <Active Source>
+    private static final int STATE_WAITING_FOR_TV_SUPPORT = 2;
     @VisibleForTesting
     static final int MAX_RETRY_COUNT = 5;
 
@@ -60,6 +63,7 @@
                 if (physicalAddress != getSourcePath()) {
                     audioSystem().setActiveSource(cmd.getSource(), physicalAddress);
                 }
+                mState = STATE_WAITING_FOR_TV_SUPPORT;
                 queryTvSystemAudioModeSupport();
                 return true;
         }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index a050aa9..4913e8b 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);
@@ -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]));
     }
 
     /**
@@ -1462,21 +1432,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 +1467,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) {
@@ -1875,30 +1853,36 @@
         // Read partner-provided list of excluded input devices
         XmlPullParser parser = null;
         // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
-        File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
-        FileReader confreader = null;
-        try {
-            confreader = new FileReader(confFile);
-            parser = Xml.newPullParser();
-            parser.setInput(confreader);
-            XmlUtils.beginDocument(parser, "devices");
+        final File[] baseDirs = {
+            Environment.getRootDirectory(),
+            Environment.getVendorDirectory()
+        };
+        for (File baseDir: baseDirs) {
+            File confFile = new File(baseDir, EXCLUDED_DEVICES_PATH);
+            FileReader confreader = null;
+            try {
+                confreader = new FileReader(confFile);
+                parser = Xml.newPullParser();
+                parser.setInput(confreader);
+                XmlUtils.beginDocument(parser, "devices");
 
-            while (true) {
-                XmlUtils.nextElement(parser);
-                if (!"device".equals(parser.getName())) {
-                    break;
+                while (true) {
+                    XmlUtils.nextElement(parser);
+                    if (!"device".equals(parser.getName())) {
+                        break;
+                    }
+                    String name = parser.getAttributeValue(null, "name");
+                    if (name != null) {
+                        names.add(name);
+                    }
                 }
-                String name = parser.getAttributeValue(null, "name");
-                if (name != null) {
-                    names.add(name);
-                }
+            } catch (FileNotFoundException e) {
+                // It's ok if the file does not exist.
+            } catch (Exception e) {
+                Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
+            } finally {
+                try { if (confreader != null) confreader.close(); } catch (IOException e) { }
             }
-        } catch (FileNotFoundException e) {
-            // It's ok if the file does not exist.
-        } catch (Exception e) {
-            Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
-        } finally {
-            try { if (confreader != null) confreader.close(); } catch (IOException e) { }
         }
 
         return names.toArray(new String[names.size()]);
@@ -2197,11 +2181,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/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index b5a9f74..3264790 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -18,45 +18,11 @@
 
 import android.content.ComponentName;
 
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-
 /**
  * Input method manager local system service interface.
  */
 public abstract class InputMethodManagerInternal {
     /**
-     * Called by the window manager service when a client process is being attached to the window
-     * manager service.
-     *
-     * <p>The caller must not have WindowManagerService lock.  This method internally acquires
-     * InputMethodManagerService lock.</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 uid UID of the client process
-     * @param pid PID of the client process
-     */
-    public abstract void addClient(IInputMethodClient client, IInputContext inputContext, int uid,
-            int pid);
-
-    /**
-     * Called by the window manager service when a client process is being attached to the window
-     * manager service.
-     *
-     * <p>The caller must not have WindowManagerService lock.  This method internally acquires
-     * InputMethodManagerService lock.</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
-     */
-    public abstract void removeClient(IInputMethodClient client);
-
-    /**
      * Called by the power manager to tell the input method manager whether it
      * should start watching for wake events.
      */
@@ -78,15 +44,6 @@
     public static final InputMethodManagerInternal NOP =
             new InputMethodManagerInternal() {
                 @Override
-                public void addClient(IInputMethodClient client, IInputContext inputContext,
-                        int uid, int pid) {
-                }
-
-                @Override
-                public void removeClient(IInputMethodClient client) {
-                }
-
-                @Override
                 public void setInteractive(boolean interactive) {
                 }
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index b2287ac..71c419f 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -401,12 +401,29 @@
         }
     }
 
+    private static final class ClientDeathRecipient implements IBinder.DeathRecipient {
+        private final InputMethodManagerService mImms;
+        private final IInputMethodClient mClient;
+
+        ClientDeathRecipient(InputMethodManagerService imms, IInputMethodClient client) {
+            mImms = imms;
+            mClient = client;
+        }
+
+        @Override
+        public void binderDied() {
+            mImms.removeClient(mClient);
+        }
+    }
+
     static final class ClientState {
         final IInputMethodClient client;
         final IInputContext inputContext;
         final int uid;
         final int pid;
+        final int selfReportedDisplayId;
         final InputBinding binding;
+        final ClientDeathRecipient clientDeathRecipient;
 
         boolean sessionRequested;
         SessionState curSession;
@@ -414,17 +431,20 @@
         @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) {
+                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;
         }
     }
 
@@ -1716,16 +1736,67 @@
         }
     }
 
-    void addClient(ClientState clientState) {
+    /**
+     * Called by each application process as a preparation to start interacting with
+     * {@link InputMethodManagerService}.
+     *
+     * <p>As a general principle, IPCs from the application process that take
+     * {@link InputMethodClient} 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,
+            int selfReportedDisplayId) {
+        final int callerUid = Binder.getCallingUid();
+        final int callerPid = Binder.getCallingPid();
         synchronized (mMethodMap) {
-            mClients.put(clientState.client.asBinder(), clientState);
+            // TODO: Optimize this linear search.
+            for (ClientState state : mClients.values()) {
+                if (state.uid == callerUid && state.pid == callerPid
+                        && state.selfReportedDisplayId == selfReportedDisplayId) {
+                    throw new SecurityException("uid=" + callerUid + "/pid=" + callerPid
+                            + " is already registered");
+                }
+            }
+            final ClientDeathRecipient deathRecipient = new ClientDeathRecipient(this, client);
+            try {
+                client.asBinder().linkToDeath(deathRecipient, 0);
+            } catch (RemoteException e) {
+                throw new IllegalStateException(e);
+            }
+            // 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));
         }
     }
 
+    private boolean verifyDisplayId(ClientState cs) {
+        return mWindowManagerInternal.isUidAllowedOnDisplay(cs.selfReportedDisplayId, cs.uid);
+    }
+
     void removeClient(IInputMethodClient client) {
         synchronized (mMethodMap) {
             ClientState cs = mClients.remove(client.asBinder());
             if (cs != null) {
+                client.asBinder().unlinkToDeath(cs.clientDeathRecipient, 0);
                 clearClientSessionLocked(cs);
                 if (mCurClient == cs) {
                     if (mBoundToMethod) {
@@ -1870,8 +1941,9 @@
         mCurAttribute = attribute;
 
         // Check if the input method is changing.
-        final int displayId = mWindowManagerInternal.getDisplayIdForWindow(
-                mCurFocusedWindow);
+        // We expect the caller has already verified that the client is allowed to access this
+        // display ID.
+        final int displayId = mCurFocusedWindowClient.selfReportedDisplayId;
         if (mCurId != null && mCurId.equals(mCurMethodId) && displayId == mCurTokenDisplayId) {
             if (cs.curSession != null) {
                 // Fast case: if we are already connected to the input method,
@@ -1928,7 +2000,7 @@
             throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
         }
 
-        unbindCurrentMethodLocked(true);
+        unbindCurrentMethodLocked();
 
         mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE);
         mCurIntent.setComponent(info.getComponent());
@@ -1936,7 +2008,11 @@
                 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);
+        if (!verifyDisplayId(mCurFocusedWindowClient)) {
+            // Wait, the client no longer has access to the display.
+            return InputBindResult.INVALID_DISPLAY_ID;
+        }
+        final int displayId = mCurFocusedWindowClient.selfReportedDisplayId;
         mCurTokenDisplayId = (displayId != INVALID_DISPLAY) ? displayId : DEFAULT_DISPLAY;
 
         if (bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) {
@@ -1972,7 +2048,7 @@
                 mCurMethod = IInputMethod.Stub.asInterface(service);
                 if (mCurToken == null) {
                     Slog.w(TAG, "Service connected without a token!");
-                    unbindCurrentMethodLocked(false);
+                    unbindCurrentMethodLocked();
                     return;
                 }
                 if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
@@ -2011,7 +2087,7 @@
         channel.dispose();
     }
 
-    void unbindCurrentMethodLocked(boolean savePosition) {
+    void unbindCurrentMethodLocked() {
         if (mVisibleBound) {
             mContext.unbindService(mVisibleConnection);
             mVisibleBound = false;
@@ -2028,10 +2104,6 @@
                     Slog.v(TAG, "Removing window token: " + mCurToken + " for display: "
                             + mCurTokenDisplayId);
                 }
-                if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0 && savePosition) {
-                    // The current IME is shown. Hence an IME switch (transition) is happening.
-                    mWindowManagerInternal.saveLastInputMethodWindowForTransition();
-                }
                 mIWindowManager.removeWindowToken(mCurToken, mCurTokenDisplayId);
             } catch (RemoteException e) {
             }
@@ -2046,7 +2118,7 @@
     void resetCurrentMethodAndClient(
             /* @InputMethodClient.UnbindReason */ final int unbindClientReason) {
         mCurMethodId = null;
-        unbindCurrentMethodLocked(false);
+        unbindCurrentMethodLocked();
         unbindCurrentClientLocked(unbindClientReason);
     }
 
@@ -2536,7 +2608,12 @@
                     // We need to check if this is the current client with
                     // focus in the window manager, to allow this call to
                     // be made before input is started in it.
-                    if (!mWindowManagerInternal.inputMethodClientHasFocus(client)) {
+                    final ClientState cs = mClients.get(client.asBinder());
+                    if (cs == null) {
+                        throw new IllegalArgumentException("unknown client " + client.asBinder());
+                    }
+                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
+                            cs.selfReportedDisplayId)) {
                         Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client);
                         return false;
                     }
@@ -2616,7 +2693,12 @@
                     // We need to check if this is the current client with
                     // focus in the window manager, to allow this call to
                     // be made before input is started in it.
-                    if (!mWindowManagerInternal.inputMethodClientHasFocus(client)) {
+                    final ClientState cs = mClients.get(client.asBinder());
+                    if (cs == null) {
+                        throw new IllegalArgumentException("unknown client " + client.asBinder());
+                    }
+                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
+                            cs.selfReportedDisplayId)) {
                         if (DEBUG) {
                             Slog.w(TAG, "Ignoring hideSoftInput of uid " + uid + ": " + client);
                         }
@@ -2715,6 +2797,8 @@
         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)
@@ -2733,8 +2817,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.inputMethodClientHasFocus(cs.client)) {
+                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
@@ -2806,10 +2897,10 @@
                                 // 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) {
-                                    unbindCurrentMethodLocked(false);
+                                // 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();
                                 }
                             }
                         } else if (isTextEditor && doAutoShow && (softInputMode &
@@ -2906,6 +2997,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;
@@ -2982,6 +3074,7 @@
     @Override
     public void showInputMethodAndSubtypeEnablerFromClient(
             IInputMethodClient client, String inputMethodId) {
+        // TODO(yukawa): Should we verify the display ID?
         if (!calledFromValidUser()) {
             return;
         }
@@ -3177,23 +3270,11 @@
      */
     @Override
     public int getInputMethodWindowVisibleHeight() {
+        // TODO(yukawa): Should we verify the display ID?
         return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId);
     }
 
     @BinderThread
-    private void clearLastInputMethodWindowForTransition(IBinder token) {
-        if (!calledFromValidUser()) {
-            return;
-        }
-        synchronized (mMethodMap) {
-            if (!calledWithValidToken(token)) {
-                return;
-            }
-        }
-        mWindowManagerInternal.clearLastInputMethodWindowForTransition();
-    }
-
-    @BinderThread
     private void notifyUserAction(@NonNull IBinder token) {
         if (DEBUG) {
             Slog.d(TAG, "Got the notification of a user action.");
@@ -4399,20 +4480,6 @@
         }
 
         @Override
-        public void addClient(IInputMethodClient client, IInputContext inputContext, int uid,
-                int pid) {
-            // Work around Bug 113877122: We need to handle this synchronously.  Otherwise, some
-            // IMM binder calls from the client process before we register this client.
-            mService.addClient(new ClientState(client, inputContext, uid, pid));
-        }
-
-        @Override
-        public void removeClient(IInputMethodClient client) {
-            // Handle this synchronously to be consistent with addClient().
-            mService.removeClient(client);
-        }
-
-        @Override
         public void setInteractive(boolean interactive) {
             // Do everything in handler so as not to block the caller.
             mService.mHandler.obtainMessage(MSG_SET_INTERACTIVE, interactive ? 1 : 0, 0)
@@ -4915,7 +4982,7 @@
             try {
                 synchronized (mMethodMap) {
                     hideCurrentInputLocked(0, null);
-                    unbindCurrentMethodLocked(false);
+                    unbindCurrentMethodLocked();
                     // Reset the current IME
                     resetSelectedInputMethodAndSubtypeLocked(null);
                     // Also reset the settings of the current IME
@@ -4988,12 +5055,6 @@
 
         @BinderThread
         @Override
-        public void clearLastInputMethodWindowForTransition() {
-            mImms.clearLastInputMethodWindowForTransition(mToken);
-        }
-
-        @BinderThread
-        @Override
         public IInputContentUriToken createInputContentUriToken(Uri contentUri,
                 String packageName) {
             return mImms.createInputContentUriToken(mToken, contentUri, packageName);
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 050a075..d326c22 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -20,6 +20,7 @@
 import static android.content.Context.BIND_AUTO_CREATE;
 import static android.content.Context.BIND_FOREGROUND_SERVICE;
 import static android.content.Context.DEVICE_POLICY_SERVICE;
+import static android.os.UserHandle.USER_ALL;
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
@@ -53,12 +54,15 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.XmlUtils;
 import com.android.server.notification.NotificationManagerService.DumpFilter;
 
@@ -72,6 +76,7 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.function.Predicate;
 
@@ -138,10 +143,6 @@
     // not mean that we are currently bound to said package/component.
     private ArrayMap<Integer, ArrayMap<Boolean, ArraySet<String>>> mApproved = new ArrayMap<>();
 
-    // Kept to de-dupe user change events (experienced after boot, when we receive a settings and a
-    // user change).
-    private int[] mLastSeenProfileIds;
-
     // True if approved services are stored in xml, not settings.
     private boolean mUseXml;
 
@@ -300,7 +301,7 @@
                 Settings.Secure.putStringForUser(
                         mContext.getContentResolver(), element, value, userId);
                 loadAllowedComponentsFromSettings();
-                rebindServices(false);
+                rebindServices(false, userId);
             }
         }
     }
@@ -385,7 +386,7 @@
                 }
             }
         }
-        rebindServices(false);
+        rebindServices(false, USER_ALL);
     }
 
     protected void upgradeXml(final int xmlVersion, final int userId) {}
@@ -460,7 +461,7 @@
             }
         }
 
-        rebindServices(false);
+        rebindServices(false, userId);
     }
 
     private String getApprovedValue(String pkgOrComponent) {
@@ -578,7 +579,7 @@
 
             if (anyServicesInvolved) {
                 // make sure we're still bound to any of our services who may have just upgraded
-                rebindServices(false);
+                rebindServices(false, USER_ALL);
             }
         }
     }
@@ -586,21 +587,17 @@
     public void onUserRemoved(int user) {
         Slog.i(TAG, "Removing approved services for removed user " + user);
         mApproved.remove(user);
-        rebindServices(true);
+        rebindServices(true, user);
     }
 
     public void onUserSwitched(int user) {
         if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user);
-        if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) {
-            if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices().");
-            return;
-        }
-        rebindServices(true);
+        rebindServices(true, user);
     }
 
     public void onUserUnlocked(int user) {
         if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user);
-        rebindServices(false);
+        rebindServices(false, user);
     }
 
     private ManagedServiceInfo getServiceFromTokenLocked(IInterface service) {
@@ -694,9 +691,10 @@
                 component.flattenToShortString());
 
         synchronized (mMutex) {
-            final int[] userIds = mUserProfiles.getCurrentProfileIds();
+            final IntArray userIds = mUserProfiles.getCurrentProfileIds();
 
-            for (int userId : userIds) {
+            for (int i = 0; i < userIds.size(); i++) {
+                final int userId = userIds.get(i);
                 if (enabled) {
                     if (isPackageOrComponentAllowed(component.toString(), userId)
                             || isPackageOrComponentAllowed(component.getPackageName(), userId)) {
@@ -838,20 +836,14 @@
         return false;
     }
 
-    /**
-     * Called whenever packages change, the user switches, or the secure setting
-     * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
-     */
-    protected void rebindServices(boolean forceRebind) {
-        if (DEBUG) Slog.d(TAG, "rebindServices");
-        final int[] userIds = mUserProfiles.getCurrentProfileIds();
-        final int nUserIds = userIds.length;
-
+    @VisibleForTesting
+    protected SparseArray<ArraySet<ComponentName>> getAllowedComponents(IntArray userIds) {
+        final int nUserIds = userIds.size();
         final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();
 
         for (int i = 0; i < nUserIds; ++i) {
-            final int userId = userIds[i];
-            final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userIds[i]);
+            final int userId = userIds.get(i);
+            final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
             if (approvedLists != null) {
                 final int N = approvedLists.size();
                 for (int j = 0; j < N; j++) {
@@ -865,67 +857,125 @@
                 }
             }
         }
+        return componentsByUser;
+    }
 
-        final ArrayList<ManagedServiceInfo> removableBoundServices = new ArrayList<>();
-        final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>();
-
-        synchronized (mMutex) {
-            // Rebind to non-system services if user switched
-            for (ManagedServiceInfo service : mServices) {
-                if (!service.isSystem && !service.isGuest(this)) {
-                    removableBoundServices.add(service);
-                }
-            }
-
-            mEnabledServicesForCurrentProfiles.clear();
-            mEnabledServicesPackageNames.clear();
-
-            for (int i = 0; i < nUserIds; ++i) {
-                // decode the list of components
-                final ArraySet<ComponentName> userComponents = componentsByUser.get(userIds[i]);
-                if (null == userComponents) {
-                    toAdd.put(userIds[i], new ArraySet<>());
-                    continue;
-                }
-
-                final Set<ComponentName> add = new HashSet<>(userComponents);
-                add.removeAll(mSnoozingForCurrentProfiles);
-
-                toAdd.put(userIds[i], add);
-
-                mEnabledServicesForCurrentProfiles.addAll(userComponents);
-
-                for (int j = 0; j < userComponents.size(); j++) {
-                    final ComponentName component = userComponents.valueAt(j);
-                    mEnabledServicesPackageNames.add(component.getPackageName());
-                }
-            }
-        }
-
-        for (ManagedServiceInfo info : removableBoundServices) {
-            final ComponentName component = info.component;
-            final int oldUser = info.userid;
-            final Set<ComponentName> allowedComponents = toAdd.get(info.userid);
-            if (allowedComponents != null) {
-                if (allowedComponents.contains(component) && !forceRebind) {
-                    // Already bound, don't need to bind again.
-                    allowedComponents.remove(component);
-                } else {
-                    // No longer allowed to be bound, or must rebind.
-                    Slog.v(TAG, "disabling " + getCaption() + " for user "
-                            + oldUser + ": " + component);
-                    unregisterService(component, oldUser);
-                }
-            }
-        }
+    @GuardedBy("mMutex")
+    protected void populateComponentsToBind(SparseArray<Set<ComponentName>> componentsToBind,
+            final IntArray activeUsers,
+            SparseArray<ArraySet<ComponentName>> approvedComponentsByUser) {
+        mEnabledServicesForCurrentProfiles.clear();
+        mEnabledServicesPackageNames.clear();
+        final int nUserIds = activeUsers.size();
 
         for (int i = 0; i < nUserIds; ++i) {
-            final Set<ComponentName> add = toAdd.get(userIds[i]);
+            // decode the list of components
+            final int userId = activeUsers.get(i);
+            final ArraySet<ComponentName> userComponents = approvedComponentsByUser.get(userId);
+            if (null == userComponents) {
+                componentsToBind.put(userId, new ArraySet<>());
+                continue;
+            }
+
+            final Set<ComponentName> add = new HashSet<>(userComponents);
+            add.removeAll(mSnoozingForCurrentProfiles);
+
+            componentsToBind.put(userId, add);
+
+            mEnabledServicesForCurrentProfiles.addAll(userComponents);
+
+            for (int j = 0; j < userComponents.size(); j++) {
+                final ComponentName component = userComponents.valueAt(j);
+                mEnabledServicesPackageNames.add(component.getPackageName());
+            }
+        }
+    }
+
+    @GuardedBy("mMutex")
+    protected Set<ManagedServiceInfo> getRemovableConnectedServices() {
+        final Set<ManagedServiceInfo> removableBoundServices = new ArraySet<>();
+        for (ManagedServiceInfo service : mServices) {
+            if (!service.isSystem && !service.isGuest(this)) {
+                removableBoundServices.add(service);
+            }
+        }
+        return removableBoundServices;
+    }
+
+    protected void populateComponentsToUnbind(
+            boolean forceRebind,
+            Set<ManagedServiceInfo> removableBoundServices,
+            SparseArray<Set<ComponentName>> allowedComponentsToBind,
+            SparseArray<Set<ComponentName>> componentsToUnbind) {
+        for (ManagedServiceInfo info : removableBoundServices) {
+            final Set<ComponentName> allowedComponents = allowedComponentsToBind.get(info.userid);
+            if (allowedComponents != null) {
+                if (forceRebind || !allowedComponents.contains(info.component)) {
+                    Set<ComponentName> toUnbind =
+                            componentsToUnbind.get(info.userid, new ArraySet<>());
+                    toUnbind.add(info.component);
+                    componentsToUnbind.put(info.userid, toUnbind);
+                }
+            }
+        }
+    }
+
+    /**
+     * Called whenever packages change, the user switches, or the secure setting
+     * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
+     */
+    protected void rebindServices(boolean forceRebind, int userToRebind) {
+        if (DEBUG) Slog.d(TAG, "rebindServices " + forceRebind + " " + userToRebind);
+        IntArray userIds = mUserProfiles.getCurrentProfileIds();
+        if (userToRebind != USER_ALL) {
+            userIds = new IntArray(1);
+            userIds.add(userToRebind);
+        }
+
+        final SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
+        final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
+
+        synchronized (mMutex) {
+            final SparseArray<ArraySet<ComponentName>> approvedComponentsByUser =
+                    getAllowedComponents(userIds);
+            final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
+
+            // Filter approvedComponentsByUser to collect all of the components that are allowed
+            // for the currently active user(s).
+            populateComponentsToBind(componentsToBind, userIds, approvedComponentsByUser);
+
+            // For every current non-system connection, disconnect services that are no longer
+            // approved, or ALL services if we are force rebinding
+            populateComponentsToUnbind(
+                    forceRebind, removableBoundServices, componentsToBind, componentsToUnbind);
+        }
+
+        unbindFromServices(componentsToUnbind);
+        bindToServices(componentsToBind);
+    }
+
+    protected void unbindFromServices(SparseArray<Set<ComponentName>> componentsToUnbind) {
+        for (int i = 0; i < componentsToUnbind.size(); i++) {
+            final int userId = componentsToUnbind.keyAt(i);
+            final Set<ComponentName> removableComponents = componentsToUnbind.get(userId);
+            for (ComponentName cn : removableComponents) {
+                // No longer allowed to be bound, or must rebind.
+                Slog.v(TAG, "disabling " + getCaption() + " for user " + userId + ": " + cn);
+                unregisterService(cn, userId);
+            }
+        }
+    }
+
+    // Attempt to bind to services, skipping those that cannot be found or lack the permission.
+    private void bindToServices(SparseArray<Set<ComponentName>> componentsToBind) {
+        for (int i = 0; i < componentsToBind.size(); i++) {
+            final int userId = componentsToBind.keyAt(i);
+            final Set<ComponentName> add = componentsToBind.get(userId);
             for (ComponentName component : add) {
                 try {
                     ServiceInfo info = mPm.getServiceInfo(component,
                             PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userIds[i]);
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
                     if (info == null) {
                         Slog.w(TAG, "Not binding " + getCaption() + " service " + component
                                 + ": service not found");
@@ -937,15 +987,13 @@
                         continue;
                     }
                     Slog.v(TAG,
-                            "enabling " + getCaption() + " for " + userIds[i] + ": " + component);
-                    registerService(component, userIds[i]);
+                            "enabling " + getCaption() + " for " + userId + ": " + component);
+                    registerService(component, userId);
                 } catch (RemoteException e) {
                     e.rethrowFromSystemServer();
                 }
             }
         }
-
-        mLastSeenProfileIds = userIds;
     }
 
     /**
@@ -1022,7 +1070,7 @@
 
                 @Override
                 public void onServiceConnected(ComponentName name, IBinder binder) {
-                    Slog.v(TAG, getCaption() + " service connected: " + name);
+                    Slog.v(TAG,  userid + " " + getCaption() + " service connected: " + name);
                     boolean added = false;
                     ManagedServiceInfo info = null;
                     synchronized (mMutex) {
@@ -1044,12 +1092,12 @@
 
                 @Override
                 public void onServiceDisconnected(ComponentName name) {
-                    Slog.v(TAG, getCaption() + " connection lost: " + name);
+                    Slog.v(TAG, userid + " " + getCaption() + " connection lost: " + name);
                 }
 
                 @Override
                 public void onBindingDied(ComponentName name) {
-                    Slog.w(TAG, getCaption() + " binding died: " + name);
+                    Slog.w(TAG,  userid + " " + getCaption() + " binding died: " + name);
                     synchronized (mMutex) {
                         unbindService(this, name, userid);
                         if (!mServicesRebinding.contains(servicesBindingTag)) {
@@ -1061,8 +1109,8 @@
                                     }
                                }, ON_BINDING_DIED_REBIND_DELAY_MS);
                         } else {
-                            Slog.v(TAG, getCaption() + " not rebinding as "
-                                    + "a previous rebind attempt was made: " + name);
+                            Slog.v(TAG, getCaption() + " not rebinding in user " + userid
+                                    + " as a previous rebind attempt was made: " + name);
                         }
                     }
                 }
@@ -1072,7 +1120,8 @@
                     getBindFlags(),
                     new UserHandle(userid))) {
                 mServicesBound.remove(servicesBindingTag);
-                Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
+                Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent
+                        + " in user " + userid);
                 return;
             }
         } catch (SecurityException ex) {
@@ -1236,9 +1285,9 @@
             if (!isEnabledForCurrentProfiles()) {
                 return false;
             }
-            if (this.userid == UserHandle.USER_ALL) return true;
+            if (this.userid == USER_ALL) return true;
             if (this.isSystem) return true;
-            if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
+            if (nid == USER_ALL || nid == this.userid) return true;
             return supportsProfiles()
                     && mUserProfiles.isCurrentProfile(nid)
                     && isPermittedForProfile(nid);
@@ -1284,6 +1333,24 @@
                 Binder.restoreCallingIdentity(identity);
             }
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            ManagedServiceInfo that = (ManagedServiceInfo) o;
+            return userid == that.userid
+                    && isSystem == that.isSystem
+                    && targetSdkVersion == that.targetSdkVersion
+                    && Objects.equals(service, that.service)
+                    && Objects.equals(component, that.component)
+                    && Objects.equals(connection, that.connection);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(service, component, userid, isSystem, connection, targetSdkVersion);
+        }
     }
 
     /** convenience method for looking in mEnabledServicesForCurrentProfiles */
@@ -1309,12 +1376,15 @@
             }
         }
 
-        public int[] getCurrentProfileIds() {
+        /**
+         * Returns the currently active users (generally one user and its work profile).
+         */
+        public IntArray getCurrentProfileIds() {
             synchronized (mCurrentProfiles) {
-                int[] users = new int[mCurrentProfiles.size()];
+                IntArray users = new IntArray(mCurrentProfiles.size());
                 final int N = mCurrentProfiles.size();
                 for (int i = 0; i < N; ++i) {
-                    users[i] = mCurrentProfiles.keyAt(i);
+                    users.add(mCurrentProfiles.keyAt(i));
                 }
                 return users;
             }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 33f0172..f9d49d7 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;
@@ -178,6 +179,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -1151,15 +1153,18 @@
                 // turn off LED when user passes through lock screen
                 mNotificationLight.turnOff();
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
-                final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
-                // reload per-user settings
-                mSettingsObserver.update(null);
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
-                // Refresh managed services
-                mConditionProviders.onUserSwitched(user);
-                mListeners.onUserSwitched(user);
-                mAssistants.onUserSwitched(user);
-                mZenModeHelper.onUserSwitched(user);
+                if (!mUserProfiles.isManagedProfile(userId)) {
+                    // reload per-user settings
+                    mSettingsObserver.update(null);
+                    // Refresh managed services
+                    mConditionProviders.onUserSwitched(userId);
+                    mListeners.onUserSwitched(userId);
+                    mZenModeHelper.onUserSwitched(userId);
+                }
+                // assistant is the only thing that cares about managed profiles specifically
+                mAssistants.onUserSwitched(userId);
             } else if (action.equals(Intent.ACTION_USER_ADDED)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 if (userId != USER_NULL) {
@@ -1169,20 +1174,23 @@
                     }
                 }
             } else if (action.equals(Intent.ACTION_USER_REMOVED)) {
-                final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
-                mZenModeHelper.onUserRemoved(user);
-                mPreferencesHelper.onUserRemoved(user);
-                mListeners.onUserRemoved(user);
-                mConditionProviders.onUserRemoved(user);
-                mAssistants.onUserRemoved(user);
+                mZenModeHelper.onUserRemoved(userId);
+                mPreferencesHelper.onUserRemoved(userId);
+                mListeners.onUserRemoved(userId);
+                mConditionProviders.onUserRemoved(userId);
+                mAssistants.onUserRemoved(userId);
                 savePolicyFile();
             } else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
-                final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
-                mConditionProviders.onUserUnlocked(user);
-                mListeners.onUserUnlocked(user);
-                mAssistants.onUserUnlocked(user);
-                mZenModeHelper.onUserUnlocked(user);
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
+                mUserProfiles.updateCache(context);
+                mAssistants.onUserUnlocked(userId);
+                if (!mUserProfiles.isManagedProfile(userId)) {
+                    mConditionProviders.onUserUnlocked(userId);
+                    mListeners.onUserUnlocked(userId);
+                    mZenModeHelper.onUserUnlocked(userId);
+                }
             }
         }
     };
@@ -1566,7 +1574,7 @@
         filter.addAction(Intent.ACTION_USER_REMOVED);
         filter.addAction(Intent.ACTION_USER_UNLOCKED);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
-        getContext().registerReceiver(mIntentReceiver, filter);
+        getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null);
 
         IntentFilter pkgFilter = new IntentFilter();
         pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -1698,10 +1706,10 @@
                     UserHandle.getUserId(uid), REASON_CHANNEL_BANNED,
                     null);
             if (isUidSystemOrPhone(uid)) {
-                int[] profileIds = mUserProfiles.getCurrentProfileIds();
-                int N = profileIds.length;
+                IntArray profileIds = mUserProfiles.getCurrentProfileIds();
+                int N = profileIds.size();
                 for (int i = 0; i < N; i++) {
-                    int profileId = profileIds[i];
+                    int profileId = profileIds.get(i);
                     cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
                             profileId, REASON_CHANNEL_BANNED,
                             null);
@@ -1994,7 +2002,8 @@
         return mInternalService;
     }
 
-    private final IBinder mService = new INotificationManager.Stub() {
+    @VisibleForTesting
+    final IBinder mService = new INotificationManager.Stub() {
         // Toasts
         // ============================================================================
 
@@ -2008,21 +2017,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) {
@@ -2390,7 +2408,7 @@
                 String pkg) {
             checkCallerIsSystemOrSameApp(pkg);
             return mPreferencesHelper.getNotificationChannelGroups(
-                    pkg, Binder.getCallingUid(), false, false);
+                    pkg, Binder.getCallingUid(), false, false, true);
         }
 
         @Override
@@ -2466,7 +2484,8 @@
         public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
                 String pkg, int uid, boolean includeDeleted) {
             checkCallerIsSystem();
-            return mPreferencesHelper.getNotificationChannelGroups(pkg, uid, includeDeleted, true);
+            return mPreferencesHelper.getNotificationChannelGroups(
+                    pkg, uid, includeDeleted, true, false);
         }
 
         @Override
@@ -4276,8 +4295,13 @@
     @VisibleForTesting
     int resolveNotificationUid(String callingPkg, String targetPkg,
             int callingUid, int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            userId = USER_SYSTEM;
+        }
         // posted from app A on behalf of app A
-        if (isCallerSameApp(targetPkg, callingUid) && TextUtils.equals(callingPkg, targetPkg)) {
+        if (isCallerSameApp(targetPkg, callingUid, userId)
+                && (TextUtils.equals(callingPkg, targetPkg)
+                || isCallerSameApp(callingPkg, callingUid, userId))) {
             return callingUid;
         }
 
@@ -4294,7 +4318,8 @@
             return targetUid;
         }
 
-        throw new SecurityException("Caller " + callingUid + " cannot post for pkg " + targetPkg);
+        throw new SecurityException("Caller " + callingPkg + ":" + callingUid
+                + " cannot post for pkg " + targetPkg + " in user " + userId);
     }
 
     /**
@@ -4314,7 +4339,7 @@
         if (!isSystemNotification && !isNotificationFromListener) {
             synchronized (mNotificationLock) {
                 if (mNotificationsByKey.get(r.sbn.getKey()) == null
-                        && isCallerInstantApp(pkg, callingUid)) {
+                        && isCallerInstantApp(pkg, Binder.getCallingUid(), userId)) {
                     // Ephemeral apps have some special constraints for notifications.
                     // They are not allowed to create new notifications however they are allowed to
                     // update notifications created by the system (e.g. a foreground service
@@ -4720,7 +4745,8 @@
                     if (notification.getSmallIcon() != null) {
                         StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
                         mListeners.notifyPostedLocked(r, old);
-                        if (oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup())) {
+                        if ((oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup()))
+                                && !isCritical(r)) {
                             mHandler.post(new Runnable() {
                                 @Override
                                 public void run() {
@@ -4890,6 +4916,19 @@
     }
 
     /**
+     * Check if the notification is classified as critical.
+     *
+     * @param record the record to test for criticality
+     * @return {@code true} if notification is considered critical
+     *
+     * @see CriticalNotificationExtractor for criteria
+     */
+    private boolean isCritical(NotificationRecord record) {
+        // 0 is the most critical
+        return record.getCriticality() < CriticalNotificationExtractor.NORMAL;
+    }
+
+    /**
      * Keeps the last 5 packages that have notified, by user.
      */
     @GuardedBy("mNotificationLock")
@@ -6408,7 +6447,8 @@
         }
     }
 
-    private boolean isCallerInstantApp(String pkg, int callingUid) {
+    @VisibleForTesting
+    boolean isCallerInstantApp(String pkg, int callingUid, int userId) {
         // System is always allowed to act for ephemeral apps.
         if (isUidSystemOrPhone(callingUid)) {
             return false;
@@ -6417,8 +6457,7 @@
         mAppOps.checkPackage(callingUid, pkg);
 
         try {
-            ApplicationInfo ai = mPackageManager.getApplicationInfo(pkg, 0,
-                    UserHandle.getCallingUserId());
+            ApplicationInfo ai = mPackageManager.getApplicationInfo(pkg, 0, userId);
             if (ai == null) {
                 throw new SecurityException("Unknown package " + pkg);
             }
@@ -6430,13 +6469,13 @@
     }
 
     private void checkCallerIsSameApp(String pkg) {
-        checkCallerIsSameApp(pkg, Binder.getCallingUid());
+        checkCallerIsSameApp(pkg, Binder.getCallingUid(), UserHandle.getCallingUserId());
     }
 
-    private void checkCallerIsSameApp(String pkg, int uid) {
+    private void checkCallerIsSameApp(String pkg, int uid, int userId) {
         try {
             ApplicationInfo ai = mPackageManager.getApplicationInfo(
-                    pkg, 0, UserHandle.getCallingUserId());
+                    pkg, 0, userId);
             if (ai == null) {
                 throw new SecurityException("Unknown package " + pkg);
             }
@@ -6458,9 +6497,9 @@
         }
     }
 
-    private boolean isCallerSameApp(String pkg, int uid) {
+    private boolean isCallerSameApp(String pkg, int uid, int userId) {
         try {
-            checkCallerIsSameApp(pkg, uid);
+            checkCallerIsSameApp(pkg, uid, userId);
             return true;
         } catch (SecurityException e) {
             return false;
@@ -6691,7 +6730,9 @@
         @Override
         public void onUserUnlocked(int user) {
             if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user);
-            rebindServices(true);
+            // force rebind the assistant, as it might be keeping its own state in user locked
+            // storage
+            rebindServices(true, user);
         }
 
         protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index fbb42ea..65ec580 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -662,10 +662,6 @@
 
     public void setContactAffinity(float contactAffinity) {
         mContactAffinity = contactAffinity;
-        if (mImportance < IMPORTANCE_DEFAULT &&
-                mContactAffinity > ValidateNotificationPeople.VALID_CONTACT) {
-            setSystemImportance(IMPORTANCE_DEFAULT);
-        }
     }
 
     public float getContactAffinity() {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 13ff6e8..3a0ab77 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -755,7 +755,7 @@
 
     @Override
     public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
-            int uid, boolean includeDeleted, boolean includeNonGrouped) {
+            int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) {
         Preconditions.checkNotNull(pkg);
         Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
         PackagePreferences r = getPackagePreferences(pkg, uid);
@@ -786,6 +786,13 @@
         if (includeNonGrouped && nonGrouped.getChannels().size() > 0) {
             groups.put(null, nonGrouped);
         }
+        if (includeEmpty) {
+            for (NotificationChannelGroup group : r.groups.values()) {
+                if (!groups.containsKey(group.getId())) {
+                    groups.put(group.getId(), group);
+                }
+            }
+        }
         return new ParceledListSlice<>(new ArrayList<>(groups.values()));
     }
 
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index af64683..605348b 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -36,7 +36,7 @@
     void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
             boolean fromTargetApp);
     ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
-            int uid, boolean includeDeleted, boolean includeNonGrouped);
+            int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
     void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
             boolean fromTargetApp, boolean hasDndAccess);
     void updateNotificationChannel(String pkg, int uid, NotificationChannel channel, boolean fromUser);
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index a178a52..2b581d6 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -15,17 +15,8 @@
  */
 package com.android.server.notification;
 
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.annotation.NonNull;
 import android.app.AlarmManager;
-import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -37,9 +28,18 @@
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -105,12 +105,12 @@
 
     protected @NonNull List<NotificationRecord> getSnoozed() {
         List<NotificationRecord> snoozedForUser = new ArrayList<>();
-        int[] userIds = mUserProfiles.getCurrentProfileIds();
+        IntArray userIds = mUserProfiles.getCurrentProfileIds();
         if (userIds != null) {
-            final int N = userIds.length;
+            final int N = userIds.size();
             for (int i = 0; i < N; i++) {
                 final ArrayMap<String, ArrayMap<String, NotificationRecord>> snoozedPkgs =
-                        mSnoozedNotifications.get(userIds[i]);
+                        mSnoozedNotifications.get(userIds.get(i));
                 if (snoozedPkgs != null) {
                     final int M = snoozedPkgs.size();
                     for (int j = 0; j < M; j++) {
@@ -179,7 +179,7 @@
     protected boolean cancel(int userId, boolean includeCurrentProfiles) {
         int[] userIds = {userId};
         if (includeCurrentProfiles) {
-            userIds = mUserProfiles.getCurrentProfileIds();
+            userIds = mUserProfiles.getCurrentProfileIds().toArray();
         }
         final int N = userIds.length;
         for (int i = 0; i < N; i++) {
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 4dd2bf2..760f155 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -52,8 +52,6 @@
 import android.service.notification.Condition;
 import android.service.notification.ConditionProviderService;
 import android.service.notification.ZenModeConfig;
-import android.service.notification.ZenModeConfig.EventInfo;
-import android.service.notification.ZenModeConfig.ScheduleInfo;
 import android.service.notification.ZenModeConfig.ZenRule;
 import android.service.notification.ZenModeProto;
 import android.util.AndroidRuntimeException;
@@ -119,8 +117,6 @@
     public static final long SUPPRESSED_EFFECT_ALL = SUPPRESSED_EFFECT_CALLS
             | SUPPRESSED_EFFECT_NOTIFICATIONS;
 
-    protected String mDefaultRuleEveryNightName;
-    protected String mDefaultRuleEventsName;
     @VisibleForTesting protected boolean mIsBootComplete;
 
     public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
@@ -130,9 +126,9 @@
         mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
         mNotificationManager =  context.getSystemService(NotificationManager.class);
 
-        mDefaultConfig = new ZenModeConfig();
-        setDefaultZenRules(mContext);
-        mConfig = mDefaultConfig;
+        mDefaultConfig = readDefaultConfig(mContext.getResources());
+        updateDefaultAutomaticRuleNames();
+        mConfig = mDefaultConfig.copy();
         mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
 
         mSettingsObserver = new SettingsObserver(mHandler);
@@ -311,7 +307,9 @@
             newConfig = mConfig.copy();
             ZenRule rule = new ZenRule();
             populateZenRule(automaticZenRule, rule, true);
-            newConfig.automaticRules.put(rule.id, rule);
+            if (newConfig.automaticRules.put(rule.id, rule) != null) {
+                rule.modified = true;
+            }
             if (setConfigLocked(newConfig, reason, rule.component, true)) {
                 return rule.id;
             } else {
@@ -341,7 +339,9 @@
                 }
             }
             populateZenRule(automaticZenRule, rule, false);
-            newConfig.automaticRules.put(ruleId, rule);
+            if (newConfig.automaticRules.put(ruleId, rule) != null) {
+                rule.modified = true;
+            }
             return setConfigLocked(newConfig, reason, rule.component, true);
         }
     }
@@ -413,17 +413,6 @@
         }
     }
 
-    public void setDefaultZenRules(Context context) {
-        mDefaultConfig = readDefaultConfig(context.getResources());
-        appendDefaultRules(mDefaultConfig);
-    }
-
-    private void appendDefaultRules (ZenModeConfig config) {
-        getDefaultRuleNames();
-        appendDefaultEveryNightRule(config);
-        appendDefaultEventRules(config);
-    }
-
     // Checks zen rule properties are the same (doesn't check creation time, name nor enabled)
     // used to check if default rules were customized or not
     private boolean ruleValuesEqual(AutomaticZenRule rule, ZenRule defaultRule) {
@@ -437,22 +426,16 @@
     }
 
     protected void updateDefaultZenRules() {
-        ZenModeConfig configDefaultRules = new ZenModeConfig();
-        appendDefaultRules(configDefaultRules); // "new" localized default rules
-        for (String ruleId : ZenModeConfig.DEFAULT_RULE_IDS) {
-            AutomaticZenRule currRule = getAutomaticZenRule(ruleId);
-            ZenRule defaultRule = configDefaultRules.automaticRules.get(ruleId);
-            // if default rule wasn't customized, use localized name instead of previous
-            if (ruleValuesEqual(currRule, defaultRule) &&
-                    !defaultRule.name.equals(currRule.getName())) {
+        updateDefaultAutomaticRuleNames();
+        for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) {
+            ZenRule currRule = mConfig.automaticRules.get(defaultRule.id);
+            // if default rule wasn't modified, use localized name instead of previous
+            if (currRule != null && !currRule.modified && !defaultRule.name.equals(currRule.name)) {
                 if (canManageAutomaticZenRule(defaultRule)) {
                     if (DEBUG) Slog.d(TAG, "Locale change - updating default zen rule name "
-                            + "from " + currRule.getName() + " to " + defaultRule.name);
+                            + "from " + currRule.name + " to " + defaultRule.name);
                     // update default rule (if locale changed, name of rule will change)
-                    AutomaticZenRule defaultAutoRule = createAutomaticZenRule(defaultRule);
-                    // ensure enabled state is carried over from current rule
-                    defaultAutoRule.setEnabled(currRule.isEnabled());
-                    updateAutomaticZenRule(ruleId, defaultAutoRule,
+                    updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(defaultRule),
                             "locale changed");
                 }
             }
@@ -642,7 +625,9 @@
                 // - doesn't already have default rules and
                 // - all previous automatic rules were disabled
                 config.automaticRules = new ArrayMap<>();
-                appendDefaultRules(config);
+                for (ZenRule rule : mDefaultConfig.automaticRules.values()) {
+                    config.automaticRules.put(rule.id, rule);
+                }
                 reason += ", reset to default rules";
             }
 
@@ -854,12 +839,16 @@
         }
     }
 
-    private void getDefaultRuleNames() {
-        // on locale-change, these values differ
-        mDefaultRuleEveryNightName = mContext.getResources()
-                .getString(R.string.zen_mode_default_every_night_name);
-        mDefaultRuleEventsName = mContext.getResources()
-                .getString(R.string.zen_mode_default_events_name);
+    private void updateDefaultAutomaticRuleNames() {
+        for (ZenRule rule : mDefaultConfig.automaticRules.values()) {
+            if (ZenModeConfig.EVENTS_DEFAULT_RULE_ID.equals(rule.id)) {
+                rule.name = mContext.getResources()
+                        .getString(R.string.zen_mode_default_events_name);
+            } else if (ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID.equals(rule.id)) {
+                rule.name = mContext.getResources()
+                        .getString(R.string.zen_mode_default_every_night_name);
+            }
+        }
     }
 
     @VisibleForTesting
@@ -1001,42 +990,6 @@
         return new ZenModeConfig();
     }
 
-    private void appendDefaultEveryNightRule(ZenModeConfig config) {
-        if (config == null) return;
-
-        final ScheduleInfo weeknights = new ScheduleInfo();
-        weeknights.days = ZenModeConfig.ALL_DAYS;
-        weeknights.startHour = 22;
-        weeknights.endHour = 7;
-        weeknights.exitAtAlarm = true;
-        final ZenRule rule = new ZenRule();
-        rule.enabled = false;
-        rule.name = mDefaultRuleEveryNightName;
-        rule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
-        rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        rule.component = ScheduleConditionProvider.COMPONENT;
-        rule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
-        rule.creationTime = System.currentTimeMillis();
-        config.automaticRules.put(rule.id, rule);
-    }
-
-    private void appendDefaultEventRules(ZenModeConfig config) {
-        if (config == null) return;
-
-        final EventInfo events = new EventInfo();
-        events.calendar = null; // any calendar
-        events.reply = EventInfo.REPLY_YES_OR_MAYBE;
-        final ZenRule rule = new ZenRule();
-        rule.enabled = false;
-        rule.name = mDefaultRuleEventsName;
-        rule.conditionId = ZenModeConfig.toEventConditionId(events);
-        rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        rule.component = EventConditionProvider.COMPONENT;
-        rule.id = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
-        rule.creationTime = System.currentTimeMillis();
-        config.automaticRules.put(rule.id, rule);
-    }
-
     private static int zenSeverity(int zen) {
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return 1;
@@ -1208,13 +1161,13 @@
         final boolean showNotification = mIsBootComplete
                 && zen != Global.ZEN_MODE_OFF
                 && !isWatch
-                && Settings.Global.getInt(mContext.getContentResolver(),
+                && Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0
-                && Settings.Global.getInt(mContext.getContentResolver(),
+                && Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ZEN_SETTINGS_UPDATED, 0) != 1;
 
         if (isWatch) {
-            Settings.Global.putInt(mContext.getContentResolver(),
+            Settings.Secure.putInt(mContext.getContentResolver(),
                     Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
         }
 
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index 5bf323a..3b11525 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -1049,7 +1049,7 @@
                                 (other != null && other.getComponentName() != null)
                                         ? other.getComponentName().getPackageName() : "?";
                         // if we're installing over the same already-installed package, this is ok
-                        if (otherPackageName != pkg.packageName) {
+                        if (!otherPackageName.equals(pkg.packageName)) {
                             throw new PackageManagerException(
                                     INSTALL_FAILED_CONFLICTING_PROVIDER,
                                     "Can't install because provider name " + names[j]
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 8f2833f..006ea75 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -21,6 +21,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
+import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
 import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDONLY;
@@ -1060,6 +1061,7 @@
     @GuardedBy("mLock")
     private void validateInstallLocked(@Nullable PackageInfo pkgInfo)
             throws PackageManagerException {
+        ApkLite baseApk = null;
         mPackageName = null;
         mVersionCode = -1;
         mSigningDetails = PackageParser.SigningDetails.UNKNOWN;
@@ -1136,6 +1138,7 @@
             // Base is coming from session
             if (apk.splitName == null) {
                 mResolvedBaseFile = targetFile;
+                baseApk = apk;
             }
 
             mResolvedStagedFiles.add(targetFile);
@@ -1221,6 +1224,7 @@
                 if (baseDexMetadataFile != null) {
                     mResolvedInheritedFiles.add(baseDexMetadataFile);
                 }
+                baseApk = existingBase;
             }
 
             // Inherit splits if not overridden
@@ -1300,6 +1304,10 @@
                 }
             }
         }
+        if (baseApk.isSplitRequired && stagedSplits.size() <= 1) {
+            throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT,
+                    "Missing split for " + mPackageName);
+        }
     }
 
     @GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 91af0ec..329b1da 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -232,6 +232,7 @@
 import android.os.storage.StorageManagerInternal;
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
+import android.permission.PermissionManager;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
 import android.security.KeyStore;
@@ -2912,13 +2913,15 @@
             if (mIsUpgrade) {
                 final int callingUid = getCallingUid();
 
-                final int numSplitPerms = PackageParser.SPLIT_PERMISSIONS.length;
+                final List<PermissionManager.SplitPermissionInfo> splitPermissions =
+                        mContext.getSystemService(PermissionManager.class).getSplitPermissions();
+                final int numSplitPerms = splitPermissions.size();
                 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
-                    final PackageParser.SplitPermissionInfo splitPerm =
-                            PackageParser.SPLIT_PERMISSIONS[splitPermNum];
-                    final String rootPerm = splitPerm.rootPerm;
+                    final PermissionManager.SplitPermissionInfo splitPerm =
+                            splitPermissions.get(splitPermNum);
+                    final String rootPerm = splitPerm.getRootPermission();
 
-                    if (preUpgradeSdkVersion >= splitPerm.targetSdk) {
+                    if (preUpgradeSdkVersion >= splitPerm.getTargetSdk()) {
                         continue;
                     }
 
@@ -2926,7 +2929,7 @@
                     for (int packageNum = 0; packageNum < numPackages; packageNum++) {
                         final PackageParser.Package pkg = mPackages.valueAt(packageNum);
 
-                        if (pkg.applicationInfo.targetSdkVersion >= splitPerm.targetSdk
+                        if (pkg.applicationInfo.targetSdkVersion >= splitPerm.getTargetSdk()
                                 || !pkg.requestedPermissions.contains(rootPerm)) {
                             continue;
                         }
@@ -2938,7 +2941,7 @@
                             continue;
                         }
 
-                        final String[] newPerms = splitPerm.newPerms;
+                        final String[] newPerms = splitPerm.getNewPermissions();
 
                         final int numNewPerms = newPerms.length;
                         for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
@@ -8471,7 +8474,7 @@
     private boolean canSkipFullApkVerification(String apkPath) {
         final byte[] rootHashObserved;
         try {
-            rootHashObserved = VerityUtils.generateFsverityRootHash(apkPath);
+            rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
             if (rootHashObserved == null) {
                 return false;  // APK does not contain Merkle tree root hash.
             }
@@ -15336,7 +15339,9 @@
             // This needs to be done before invoking dexopt so that any install-time profile
             // can be used for optimizations.
             mArtManagerService.prepareAppProfiles(
-                    pkg, resolveUserIds(reconciledPkg.installForUser.getIdentifier()));
+                    pkg,
+                    resolveUserIds(reconciledPkg.installForUser.getIdentifier()),
+                    /* updateReferenceProfileContent= */ true);
 
             // Check whether we need to dexopt the app.
             //
@@ -15999,12 +16004,14 @@
             }
             if (apkPath != null) {
                 final VerityUtils.SetupResult result =
-                        VerityUtils.generateApkVeritySetupData(apkPath);
+                        VerityUtils.generateApkVeritySetupData(apkPath, null /* signaturePath */,
+                                true /* skipSigningBlock */);
                 if (result.isOk()) {
                     if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling apk verity to " + apkPath);
                     FileDescriptor fd = result.getUnownedFileDescriptor();
                     try {
-                        final byte[] signedRootHash = VerityUtils.generateFsverityRootHash(apkPath);
+                        final byte[] signedRootHash =
+                                VerityUtils.generateApkVerityRootHash(apkPath);
                         mInstaller.installApkVerity(apkPath, fd, result.getContentSize());
                         mInstaller.assertFsverityRootHashMatches(apkPath, signedRootHash);
                     } catch (InstallerException | IOException | DigestException |
@@ -21184,8 +21191,18 @@
         //
         // We also have to cover non system users because we do not call the usual install package
         // methods for them.
+        //
+        // NOTE: in order to speed up first boot time we only create the current profile and do not
+        // update the content of the reference profile. A system image should already be configured
+        // with the right profile keys and the profiles for the speed-profile prebuilds should
+        // already be copied. That's done in #performDexOptUpgrade.
+        //
+        // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
+        // manually copying them in #performDexOptUpgrade. When we do that we should have a more
+        // granular check here and only update the existing profiles.
         if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
-            mArtManagerService.prepareAppProfiles(pkg, userId);
+            mArtManagerService.prepareAppProfiles(pkg, userId,
+                /* updateReferenceProfileContent= */ false);
         }
 
         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
@@ -23082,7 +23099,9 @@
                 return false;
             }
         }
-        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
+        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
+                  || sUserManager.hasUserRestriction(
+                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
             return false;
         }
         if (mExternalSourcesPolicy != null) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 361416a..93729d1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -124,6 +124,7 @@
     int mTargetUser;
     boolean mBrief;
     boolean mComponents;
+    int mQueryFlags;
 
     PackageManagerShellCommand(PackageManagerService service) {
         mInterface = service;
@@ -739,6 +740,9 @@
                 } else if ("--components".equals(opt)) {
                     mComponents = true;
                     return true;
+                } else if ("--query-flags".equals(opt)) {
+                    mQueryFlags = Integer.decode(cmd.getNextArgRequired());
+                    return true;
                 }
                 return false;
             }
@@ -784,7 +788,8 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
+            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
+                    mTargetUser);
             PrintWriter pw = getOutPrintWriter();
             if (ri == null) {
                 pw.println("No activity found");
@@ -806,8 +811,8 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
-                    mTargetUser).getList();
+            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(),
+                    mQueryFlags, mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
                 pw.println("No activities found");
@@ -840,8 +845,8 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
-                    mTargetUser).getList();
+            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(),
+                    mQueryFlags, mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
                 pw.println("No services found");
@@ -874,8 +879,8 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
-                    mTargetUser).getList();
+            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(),
+                    mQueryFlags, mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
                 pw.println("No receivers found");
@@ -2234,6 +2239,9 @@
                 case "--install-location":
                     sessionParams.installLocation = Integer.parseInt(getNextArg());
                     break;
+                case "--install-reason":
+                    sessionParams.installReason = Integer.parseInt(getNextArg());
+                    break;
                 case "--force-uuid":
                     sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
                     sessionParams.volumeUuid = getNextArg();
@@ -2728,22 +2736,26 @@
         pw.println("      -d: only list dangerous permissions");
         pw.println("      -u: list only the permissions users will see");
         pw.println("");
-        pw.println("  resolve-activity [--brief] [--components] [--user USER_ID] INTENT");
+        pw.println("  resolve-activity [--brief] [--components] [--query-flags FLAGS]");
+        pw.println("       [--user USER_ID] INTENT");
         pw.println("    Prints the activity that resolves to the given INTENT.");
         pw.println("");
-        pw.println("  query-activities [--brief] [--components] [--user USER_ID] INTENT");
+        pw.println("  query-activities [--brief] [--components] [--query-flags FLAGS]");
+        pw.println("       [--user USER_ID] INTENT");
         pw.println("    Prints all activities that can handle the given INTENT.");
         pw.println("");
-        pw.println("  query-services [--brief] [--components] [--user USER_ID] INTENT");
+        pw.println("  query-services [--brief] [--components] [--query-flags FLAGS]");
+        pw.println("       [--user USER_ID] INTENT");
         pw.println("    Prints all services that can handle the given INTENT.");
         pw.println("");
-        pw.println("  query-receivers [--brief] [--components] [--user USER_ID] INTENT");
+        pw.println("  query-receivers [--brief] [--components] [--query-flags FLAGS]");
+        pw.println("       [--user USER_ID] INTENT");
         pw.println("    Prints all broadcast receivers that can handle the given INTENT.");
         pw.println("");
         pw.println("  install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
         pw.println("       [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
-        pw.println("       [--originating-uri URI] [---referrer URI]");
-        pw.println("       [--abi ABI_NAME] [--force-sdk]");
+        pw.println("       [--install-reason 0/1/2/3/4] [--originating-uri URI]");
+        pw.println("       [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
         pw.println("       [--preload] [--instantapp] [--full] [--dont-kill]");
         pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]");
         pw.println("    Install an application.  Must provide the apk data to install, either as a");
@@ -2768,14 +2780,17 @@
         pw.println("      --full: cause the app to be installed as a non-ephemeral full app");
         pw.println("      --install-location: force the install location:");
         pw.println("          0=auto, 1=internal only, 2=prefer external");
+        pw.println("      --install-reason: indicates why the app is being installed:");
+        pw.println("          0=unknown, 1=admin policy, 2=device restore,");
+        pw.println("          3=device setup, 4=user request");
         pw.println("      --force-uuid: force install on to disk volume with given UUID");
         pw.println("      --force-sdk: allow install even when existing app targets platform");
         pw.println("          codename but new one targets a final API level");
         pw.println("");
         pw.println("  install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
         pw.println("       [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
-        pw.println("       [--originating-uri URI] [---referrer URI]");
-        pw.println("       [--abi ABI_NAME] [--force-sdk]");
+        pw.println("       [--install-reason 0/1/2/3/4] [--originating-uri URI]");
+        pw.println("       [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
         pw.println("       [--preload] [--instantapp] [--full] [--dont-kill]");
         pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
         pw.println("    Like \"install\", but starts an install session.  Use \"install-write\"");
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/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 3f28ee6..1315502 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -16,10 +16,6 @@
 
 package com.android.server.pm;
 
-import com.google.android.collect.Sets;
-
-import com.android.internal.util.Preconditions;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -42,6 +38,10 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.util.Preconditions;
+
+import com.google.android.collect.Sets;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlSerializer;
 
@@ -77,6 +77,7 @@
             UserManager.DISALLOW_UNINSTALL_APPS,
             UserManager.DISALLOW_SHARE_LOCATION,
             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
             UserManager.DISALLOW_CONFIG_BLUETOOTH,
             UserManager.DISALLOW_BLUETOOTH,
             UserManager.DISALLOW_BLUETOOTH_SHARING,
@@ -211,7 +212,8 @@
      */
     private static final Set<String> PROFILE_GLOBAL_RESTRICTIONS = Sets.newArraySet(
             UserManager.ENSURE_VERIFY_APPS,
-            UserManager.DISALLOW_AIRPLANE_MODE
+            UserManager.DISALLOW_AIRPLANE_MODE,
+            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY
     );
 
     /**
@@ -517,13 +519,18 @@
                                 userId);
                     }
                     break;
+                case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY:
+                    setInstallMarketAppsRestriction(cr, userId, getNewUserRestrictionSetting(
+                            context, userId, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+                            newValue));
+                    break;
                 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES:
                     // Since Android O, the secure setting is not available to be changed by the
                     // user. Hence, when the restriction is cleared, we need to reset the state of
                     // the setting to its default value which is now 1.
-                    android.provider.Settings.Secure.putIntForUser(cr,
-                            android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
-                            newValue ? 0 : 1, userId);
+                    setInstallMarketAppsRestriction(cr, userId, getNewUserRestrictionSetting(
+                            context, userId, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,
+                            newValue));
                     break;
                 case UserManager.DISALLOW_RUN_IN_BACKGROUND:
                     if (newValue) {
@@ -813,4 +820,16 @@
         }
         return false;
     }
+
+    private static void setInstallMarketAppsRestriction(ContentResolver cr, int userId,
+            int settingValue) {
+        android.provider.Settings.Secure.putIntForUser(
+                cr, android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, settingValue, userId);
+    }
+
+    private static int getNewUserRestrictionSetting(Context context, int userId,
+                String userRestriction, boolean newValue) {
+        return (newValue || UserManager.get(context).hasUserRestriction(userRestriction,
+                UserHandle.of(userId))) ? 0 : 1;
+    }
 }
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 21daa39..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;
@@ -389,7 +389,8 @@
      *   - create the current primary profile to save time at app startup time.
      *   - copy the profiles from the associated dex metadata file to the reference profile.
      */
-    public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user) {
+    public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user,
+            boolean updateReferenceProfileContent) {
         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
         if (user < 0) {
             Slog.wtf(TAG, "Invalid user id: " + user);
@@ -404,8 +405,14 @@
             for (int i = codePathsProfileNames.size() - 1; i >= 0; i--) {
                 String codePath = codePathsProfileNames.keyAt(i);
                 String profileName = codePathsProfileNames.valueAt(i);
-                File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath));
-                String dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath();
+                String dexMetadataPath = null;
+                // Passing the dex metadata file to the prepare method will update the reference
+                // profile content. As such, we look for the dex metadata file only if we need to
+                // perform an update.
+                if (updateReferenceProfileContent) {
+                    File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath));
+                    dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath();
+                }
                 synchronized (mInstaller) {
                     boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId,
                             profileName, codePath, dexMetadataPath);
@@ -423,9 +430,10 @@
     /**
      * Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}.
      */
-    public void prepareAppProfiles(PackageParser.Package pkg, int[] user) {
+    public void prepareAppProfiles(PackageParser.Package pkg, int[] user,
+            boolean updateReferenceProfileContent) {
         for (int i = 0; i < user.length; i++) {
-            prepareAppProfiles(pkg, user[i]);
+            prepareAppProfiles(pkg, user[i], updateReferenceProfileContent);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index e3e1590..602ce3b 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -93,7 +93,7 @@
     @GuardedBy("mPackageUseInfoMap")
     private final Map<String, PackageUseInfo> mPackageUseInfoMap;
 
-    public PackageDexUsage() {
+    /* package */ PackageDexUsage() {
         super("package-dex-usage.list", "PackageDexUsage_DiskWriter", /*lock*/ false);
         mPackageUseInfoMap = new HashMap<>();
     }
@@ -116,7 +116,7 @@
      * @return true if the dex load constitutes new information, or false if this information
      *         has been seen before.
      */
-    public boolean record(String owningPackageName, String dexPath, int ownerUserId,
+    /* package */ boolean record(String owningPackageName, String dexPath, int ownerUserId,
             String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit,
             String loadingPackageName, String classLoaderContext) {
         if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
@@ -193,7 +193,7 @@
      * Convenience method for sync reads which does not force the user to pass a useless
      * (Void) null.
      */
-    public void read() {
+    /* package */ void read() {
       read((Void) null);
     }
 
@@ -558,7 +558,7 @@
      * Remove the usage data associated with package {@code packageName}.
      * @return true if the package usage was found and removed successfully.
      */
-    public boolean removePackage(String packageName) {
+    /* package */ boolean removePackage(String packageName) {
         synchronized (mPackageUseInfoMap) {
             return mPackageUseInfoMap.remove(packageName) != null;
         }
@@ -653,11 +653,12 @@
         return packages;
     }
 
-    public void clear() {
+    /* package */ void clear() {
         synchronized (mPackageUseInfoMap) {
             mPackageUseInfoMap.clear();
         }
     }
+
     // Creates a deep copy of the class' mPackageUseInfoMap.
     private Map<String, PackageUseInfo> clonePackageUseInfoMap() {
         Map<String, PackageUseInfo> clone = new HashMap<>();
@@ -679,7 +680,7 @@
         throw new IllegalArgumentException("Unknown bool encoding: " + bool);
     }
 
-    public String dump() {
+    /* package */ String dump() {
         StringWriter sw = new StringWriter();
         write(sw);
         return sw.toString();
diff --git a/services/core/java/com/android/server/pm/dex/TEST_MAPPING b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
new file mode 100644
index 0000000..ad52559
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
@@ -0,0 +1,22 @@
+{
+  "presubmit": [
+    {
+      "name": "DexLoggerTests"
+    },
+    {
+      "name": "DexManagerTests"
+    },
+    {
+      "name": "DexoptOptionsTests"
+    },
+    {
+      "name": "DexoptUtilsTest"
+    },
+    {
+      "name": "PackageDexUsageTests"
+    },
+    {
+      "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 d9eb7e8..6f644dd 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -34,7 +34,6 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageManagerInternal.PackagesProvider;
 import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
-import android.content.pm.PackageParser;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.media.RingtoneManager;
@@ -48,6 +47,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
+import android.permission.PermissionManager;
 import android.print.PrintManager;
 import android.provider.CalendarContract;
 import android.provider.ContactsContract;
@@ -946,7 +946,7 @@
     }
 
     private boolean isSystemPackage(String packageName) {
-        return isSystemPackage(getSystemPackageInfo(packageName));
+        return isSystemPackage(getPackageInfo(packageName));
     }
 
     private boolean isSystemPackage(PackageInfo pkg) {
@@ -1024,15 +1024,17 @@
         ApplicationInfo applicationInfo = pkg.applicationInfo;
 
         // Automatically attempt to grant split permissions to older APKs
-        final int numSplitPerms = PackageParser.SPLIT_PERMISSIONS.length;
+        final List<PermissionManager.SplitPermissionInfo> splitPermissions =
+                mContext.getSystemService(PermissionManager.class).getSplitPermissions();
+        final int numSplitPerms = splitPermissions.size();
         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
-            final PackageParser.SplitPermissionInfo splitPerm =
-                    PackageParser.SPLIT_PERMISSIONS[splitPermNum];
+            final PermissionManager.SplitPermissionInfo splitPerm =
+                    splitPermissions.get(splitPermNum);
 
             if (applicationInfo != null
-                    && applicationInfo.targetSdkVersion < splitPerm.targetSdk
-                    && permissionsWithoutSplits.contains(splitPerm.rootPerm)) {
-                Collections.addAll(permissions, splitPerm.newPerms);
+                    && applicationInfo.targetSdkVersion < splitPerm.getTargetSdk()
+                    && permissionsWithoutSplits.contains(splitPerm.getRootPermission())) {
+                Collections.addAll(permissions, splitPerm.getNewPermissions());
             }
         }
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java
index 5e66bfc3..82d6b22 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java
@@ -135,7 +135,8 @@
             final int userCount = other.mPermissionReviewRequired.size();
             for (int i = 0; i < userCount; i++) {
                 final boolean reviewRequired = other.mPermissionReviewRequired.valueAt(i);
-                mPermissionReviewRequired.put(i, reviewRequired);
+                mPermissionReviewRequired.put(other.mPermissionReviewRequired.keyAt(i),
+                        reviewRequired);
             }
         }
     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3b19beb..21bf488 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -125,6 +125,7 @@
 import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
 import static android.view.WindowManagerGlobal.ADD_OKAY;
 import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
+
 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -532,8 +533,6 @@
 
     GlobalActions mGlobalActions;
     Handler mHandler;
-    WindowState mLastInputMethodWindow = null;
-    WindowState mLastInputMethodTargetWindow = null;
 
     // FIXME This state is shared between the input reader and handler thread.
     // Technically it's broken and buggy but it has been like this for many years
@@ -631,9 +630,11 @@
 
     InputConsumer mInputConsumer = null;
 
-    private final WindowFrames mWindowFrames = new WindowFrames();
-    private static final Rect mTmpDisplayCutoutSafeExceptMaybeBarsRect = new Rect();
-    private static final Rect mTmpRect = new Rect();
+    private static final Rect sTmpDisplayCutoutSafeExceptMaybeBarsRect = new Rect();
+    private static final Rect sTmpRect = new Rect();
+    private static final Rect sTmpDockedFrame = new Rect();
+    private static final Rect sTmpNavFrame = new Rect();
+    private static final Rect sTmpLastParentFrame = new Rect();
 
     WindowState mTopFullscreenOpaqueWindowState;
     WindowState mTopFullscreenOpaqueOrDimmingWindowState;
@@ -1654,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() {
@@ -2827,7 +2826,8 @@
                 // Assumes it's safe to show starting windows of launched apps while
                 // the keyguard is being hidden. This is okay because starting windows never show
                 // secret information.
-                if (mKeyguardOccluded) {
+                // TODO(b/113840485): Occluded may not only happen on default display
+                if (displayId == DEFAULT_DISPLAY && mKeyguardOccluded) {
                     windowFlags |= FLAG_SHOW_WHEN_LOCKED;
                 }
             }
@@ -4308,9 +4308,6 @@
         mDockLayer = 0x10000000;
         mStatusBarLayer = -1;
 
-        mWindowFrames.setDisplayCutout(displayFrames.mDisplayCutout);
-        mWindowFrames.setParentFrameWasClippedByDisplayCutout(false);
-
         if (displayFrames.mDisplayId == DEFAULT_DISPLAY) {
             // For purposes of putting out fake window up to steal focus, we will
             // drive nav being hidden only by whether it is requested.
@@ -4377,12 +4374,8 @@
             return;
         }
 
-        mTmpRect.setEmpty();
-        mWindowFrames.setFrames(displayFrames.mDock /* parentFrame */,
-                displayFrames.mDock /* displayFrame */, displayFrames.mDock /* overscanFrame */,
-                displayFrames.mDock /* contentFrame */, displayFrames.mDock /* visibleFrame */,
-                mTmpRect /* decorFrame */, displayFrames.mDock /* stableFrame */,
-                displayFrames.mDock /* outsetFrame */);
+        sTmpRect.setEmpty();
+        sTmpDockedFrame.set(displayFrames.mDock);
 
         final int displayId = displayFrames.mDisplayId;
         final Rect dockFrame = displayFrames.mDock;
@@ -4396,7 +4389,13 @@
                 continue;
             }
 
-            w.computeFrameLw(mWindowFrames);
+            w.getWindowFrames().setFrames(sTmpDockedFrame /* parentFrame */,
+                    sTmpDockedFrame /* displayFrame */, sTmpDockedFrame /* overscanFrame */,
+                    sTmpDockedFrame /* contentFrame */, sTmpDockedFrame /* visibleFrame */,
+                    sTmpRect /* decorFrame */, sTmpDockedFrame /* stableFrame */,
+                    sTmpDockedFrame /* outsetFrame */);
+            w.getWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout);
+            w.computeFrameLw();
             final Rect frame = w.getFrameLw();
 
             if (frame.left <= 0 && frame.top <= 0) {
@@ -4448,17 +4447,17 @@
             return false;
         }
         // apply any navigation bar insets
-        mTmpRect.setEmpty();
-        mWindowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */,
+        sTmpRect.setEmpty();
+        mStatusBar.getWindowFrames().setFrames(displayFrames.mUnrestricted /* parentFrame */,
                 displayFrames.mUnrestricted /* displayFrame */,
                 displayFrames.mStable /* overscanFrame */, displayFrames.mStable /* contentFrame */,
-                displayFrames.mStable /* visibleFrame */, mTmpRect /* decorFrame */,
+                displayFrames.mStable /* visibleFrame */, sTmpRect /* decorFrame */,
                 displayFrames.mStable /* stableFrame */, displayFrames.mStable /* outsetFrame */);
-
+        mStatusBar.getWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout);
         mStatusBarLayer = mStatusBar.getSurfaceLayer();
 
         // Let the status bar determine its size.
-        mStatusBar.computeFrameLw(mWindowFrames);
+        mStatusBar.computeFrameLw();
 
         // For layout, the status bar is always at the top with our fixed height.
         displayFrames.mStable.top = displayFrames.mUnrestricted.top
@@ -4468,11 +4467,11 @@
                 displayFrames.mDisplayCutoutSafe.top);
 
         // Tell the bar controller where the collapsed status bar content is
-        mTmpRect.set(mStatusBar.getContentFrameLw());
-        mTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
-        mTmpRect.top = mStatusBar.getContentFrameLw().top;  // Ignore top display cutout inset
-        mTmpRect.bottom = displayFrames.mStable.top;  // Use collapsed status bar size
-        mStatusBarController.setContentFrame(mTmpRect);
+        sTmpRect.set(mStatusBar.getContentFrameLw());
+        sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
+        sTmpRect.top = mStatusBar.getContentFrameLw().top;  // Ignore top display cutout inset
+        sTmpRect.bottom = displayFrames.mStable.top;  // Use collapsed status bar size
+        mStatusBarController.setContentFrame(sTmpRect);
 
         boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
         boolean statusBarTranslucent = (sysui
@@ -4512,7 +4511,7 @@
             return false;
         }
 
-        final Rect navigationFrame = mWindowFrames.mParentFrame;
+        final Rect navigationFrame = sTmpNavFrame;
         boolean transientNavBarShowing = mNavigationBarController.isTransientShowing();
         // Force the navigation bar to its appropriate place and size. We need to do this directly,
         // instead of relying on it to bubble up from the nav bar, because this needs to change
@@ -4523,7 +4522,7 @@
         final Rect dockFrame = displayFrames.mDock;
         mNavigationBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation);
 
-        final Rect cutoutSafeUnrestricted = mTmpRect;
+        final Rect cutoutSafeUnrestricted = sTmpRect;
         cutoutSafeUnrestricted.set(displayFrames.mUnrestricted);
         cutoutSafeUnrestricted.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
 
@@ -4605,15 +4604,15 @@
         displayFrames.mContent.set(dockFrame);
         mStatusBarLayer = mNavigationBar.getSurfaceLayer();
         // And compute the final frame.
-        mTmpRect.setEmpty();
-        mWindowFrames.setFrames(navigationFrame /* parentFrame */,
+        sTmpRect.setEmpty();
+        mNavigationBar.getWindowFrames().setFrames(navigationFrame /* parentFrame */,
                 navigationFrame /* displayFrame */, navigationFrame /* overscanFrame */,
                 displayFrames.mDisplayCutoutSafe /* contentFrame */,
-                navigationFrame /* visibleFrame */, mTmpRect /* decorFrame */,
+                navigationFrame /* visibleFrame */, sTmpRect /* decorFrame */,
                 navigationFrame /* stableFrame */,
                 displayFrames.mDisplayCutoutSafe /* outsetFrame */);
-
-        mNavigationBar.computeFrameLw(mWindowFrames);
+        mNavigationBar.getWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout);
+        mNavigationBar.computeFrameLw();
         mNavigationBarController.setContentFrame(mNavigationBar.getContentFrameLw());
 
         if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + navigationFrame);
@@ -4730,12 +4729,6 @@
         }
         final WindowManager.LayoutParams attrs = win.getAttrs();
         final boolean isDefaultDisplay = win.isDefaultDisplay();
-        final boolean needsToOffsetInputMethodTarget =
-                (win == mLastInputMethodTargetWindow) && (mLastInputMethodWindow != null);
-        if (needsToOffsetInputMethodTarget) {
-            if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state");
-            offsetInputMethodWindowLw(mLastInputMethodWindow, displayFrames);
-        }
 
         final int type = attrs.type;
         final int fl = PolicyControl.getWindowFlags(win, attrs);
@@ -4744,17 +4737,20 @@
         final int requestedSysUiFl = PolicyControl.getSystemUiVisibility(null, attrs);
         final int sysUiFl = requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs);
 
-        final Rect pf = mWindowFrames.mParentFrame;
-        final Rect df = mWindowFrames.mDisplayFrame;
-        final Rect of = mWindowFrames.mOverscanFrame;
-        final Rect cf = mWindowFrames.mContentFrame;
-        final Rect vf = mWindowFrames.mVisibleFrame;
-        final Rect dcf = mWindowFrames.mDecorFrame;
-        final Rect sf = mWindowFrames.mStableFrame;
+        final WindowFrames windowFrames = win.getWindowFrames();
+
+        windowFrames.setHasOutsets(false);
+        sTmpLastParentFrame.set(windowFrames.mParentFrame);
+        final Rect pf = windowFrames.mParentFrame;
+        final Rect df = windowFrames.mDisplayFrame;
+        final Rect of = windowFrames.mOverscanFrame;
+        final Rect cf = windowFrames.mContentFrame;
+        final Rect vf = windowFrames.mVisibleFrame;
+        final Rect dcf = windowFrames.mDecorFrame;
+        final Rect sf = windowFrames.mStableFrame;
         dcf.setEmpty();
-        mWindowFrames.mOutsetFrame.setEmpty();
-        mWindowFrames.setParentFrameWasClippedByDisplayCutout(false);
-        mWindowFrames.setDisplayCutout(displayFrames.mDisplayCutout);
+        windowFrames.setParentFrameWasClippedByDisplayCutout(false);
+        windowFrames.setDisplayCutout(displayFrames.mDisplayCutout);
 
         final boolean hasNavBar = (isDefaultDisplay && mDefaultDisplayPolicy.hasNavigationBar()
                 && mNavigationBar != null && mNavigationBar.isVisibleLw());
@@ -4774,11 +4770,12 @@
             cf.set(displayFrames.mDock);
             of.set(displayFrames.mDock);
             df.set(displayFrames.mDock);
-            pf.set(displayFrames.mDock);
+            windowFrames.mParentFrame.set(displayFrames.mDock);
             // IM dock windows layout below the nav bar...
             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.
@@ -4876,9 +4873,7 @@
                                 ? displayFrames.mRestricted.bottom
                                 : displayFrames.mUnrestricted.bottom;
 
-                        if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
-                                        "Laying out status bar window: (%d,%d - %d,%d)",
-                                        pf.left, pf.top, pf.right, pf.bottom));
+                        if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out status bar window: " + pf);
                     } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0
                             && type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW) {
                         // Asking to layout into the overscan region, so give it that pure
@@ -4950,17 +4945,13 @@
                         pf.bottom = df.bottom = of.bottom = cf.bottom =
                                 displayFrames.mRestricted.bottom;
                     }
-                    if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
-                            "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
-                            pf.left, pf.top, pf.right, pf.bottom));
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out IN_SCREEN status bar window: " + pf);
                 } else if (type == TYPE_NAVIGATION_BAR || type == TYPE_NAVIGATION_BAR_PANEL) {
                     // The navigation bar has Real Ultimate Power.
                     of.set(displayFrames.mUnrestricted);
                     df.set(displayFrames.mUnrestricted);
                     pf.set(displayFrames.mUnrestricted);
-                    if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
-                                    "Laying out navigation bar window: (%d,%d - %d,%d)",
-                                    pf.left, pf.top, pf.right, pf.bottom));
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out navigation bar window: " + pf);
                 } else if ((type == TYPE_SECURE_SYSTEM_OVERLAY || type == TYPE_SCREENSHOT)
                         && ((fl & FLAG_FULLSCREEN) != 0)) {
                     // Fullscreen secure system overlays get what they ask for. Screenshot region
@@ -5087,7 +5078,7 @@
         // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
         // the cutout safe zone.
         if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
-            final Rect displayCutoutSafeExceptMaybeBars = mTmpDisplayCutoutSafeExceptMaybeBarsRect;
+            final Rect displayCutoutSafeExceptMaybeBars = sTmpDisplayCutoutSafeExceptMaybeBarsRect;
             displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
             if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
                     && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
@@ -5122,9 +5113,9 @@
             // They will later be cropped or shifted using the displayFrame in WindowState,
             // which prevents overlap with the DisplayCutout.
             if (!attachedInParent && !floatingInScreenWindow) {
-                mTmpRect.set(pf);
+                sTmpRect.set(pf);
                 pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
-                mWindowFrames.setParentFrameWasClippedByDisplayCutout(!mTmpRect.equals(pf));
+                windowFrames.setParentFrameWasClippedByDisplayCutout(!sTmpRect.equals(pf));
             }
             // Make sure that NO_LIMITS windows clipped to the display don't extend under the
             // cutout.
@@ -5152,8 +5143,9 @@
         // apply the outsets to floating dialogs, because they wouldn't make sense there.
         final boolean useOutsets = shouldUseOutsets(attrs, fl);
         if (isDefaultDisplay && useOutsets) {
-            final Rect osf = mWindowFrames.mOutsetFrame;
+            final Rect osf = windowFrames.mOutsetFrame;
             osf.set(cf.left, cf.top, cf.right, cf.bottom);
+            windowFrames.setHasOutsets(true);
             int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
             if (outset > 0) {
                 int rotation = displayFrames.mRotation;
@@ -5180,14 +5172,17 @@
                 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()
                 + " dcf=" + dcf.toShortString()
                 + " sf=" + sf.toShortString()
-                + " osf=" + mWindowFrames.mOutsetFrame.toShortString());
+                + " osf=" + windowFrames.mOutsetFrame.toShortString() + " " + win);
 
-        win.computeFrameLw(mWindowFrames);
+        if (!sTmpLastParentFrame.equals(pf)) {
+            windowFrames.setContentChanged(true);
+        }
+
+        win.computeFrameLw();
         // Dock windows carve out the bottom of the screen, so normal windows
         // can't appear underneath them.
         if (type == TYPE_INPUT_METHOD && win.isVisibleLw()
                 && !win.getGivenInsetsPendingLw()) {
-            setLastInputMethodWindowLw(null, null);
             offsetInputMethodWindowLw(win, displayFrames);
         }
         if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw()
@@ -7818,12 +7813,6 @@
     }
 
     @Override
-    public void setLastInputMethodWindowLw(WindowState ime, WindowState target) {
-        mLastInputMethodWindow = ime;
-        mLastInputMethodTargetWindow = target;
-    }
-
-    @Override
     public void setDismissImeOnBackKeyPressed(boolean newValue) {
         mDismissImeOnBackKeyPressed = newValue;
     }
@@ -7841,7 +7830,6 @@
         if (statusBar != null) {
             statusBar.setCurrentUser(newUserId);
         }
-        setLastInputMethodWindowLw(null, null);
     }
 
     @Override
@@ -8016,14 +8004,6 @@
         pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream);
                 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen);
                 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
-        if (mLastInputMethodWindow != null) {
-            pw.print(prefix); pw.print("mLastInputMethodWindow=");
-                    pw.println(mLastInputMethodWindow);
-        }
-        if (mLastInputMethodTargetWindow != null) {
-            pw.print(prefix); pw.print("mLastInputMethodTargetWindow=");
-                    pw.println(mLastInputMethodTargetWindow);
-        }
         if (mStatusBar != null) {
             pw.print(prefix); pw.print("mStatusBar=");
                     pw.print(mStatusBar); pw.print(" isStatusBarKeyguard=");
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
new file mode 100644
index 0000000..e212b04
--- /dev/null
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -0,0 +1,50 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.policy."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "android.support.test.filters.FlakyTest"
+        }
+      ]
+    },
+    {
+      "name": "WmTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.policy."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    }
+  ],
+  "postsubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.policy."
+        }
+      ]
+    },
+    {
+      "name": "WmTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.policy."
+        }
+      ]
+    }
+  ]
+}
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index b55adeb..27ab3ef 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -63,12 +63,10 @@
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
-import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
-import android.content.pm.ActivityInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -95,7 +93,6 @@
 import com.android.server.wm.DisplayFrames;
 import com.android.server.wm.DisplayRotation;
 import com.android.server.wm.WindowFrames;
-import com.android.server.wm.utils.WmDisplayCutout;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -201,10 +198,8 @@
          * getFrame() if so desired.  Must be called with the window manager
          * lock held.
          *
-         * @param windowFrames Container for all the window frames that affect how the window is
-         *                     laid out.
          */
-        public void computeFrameLw(WindowFrames windowFrames);
+        public void computeFrameLw();
 
         /**
          * Retrieve the current frame of the window that has been assigned by
@@ -477,6 +472,11 @@
          * Writes {@link com.android.server.wm.IdentifierProto} to stream.
          */
         void writeIdentifierToProto(ProtoOutputStream proto, long fieldId);
+
+        /**
+         * @return The {@link WindowFrames} associated with this {@link WindowState}
+         */
+        WindowFrames getWindowFrames();
     }
 
     /**
@@ -1167,7 +1167,6 @@
     default void layoutWindowLw(
             WindowState win, WindowState attached, DisplayFrames displayFrames) {}
 
-
     /**
      * Return the layout hints for a newly added window. These values are computed on the
      * most recent layout, so they are not guaranteed to be correct.
@@ -1537,13 +1536,6 @@
     public void lockNow(Bundle options);
 
     /**
-     * Set the last used input method window state. This state is used to make IME transition
-     * smooth.
-     * @hide
-     */
-    public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
-
-    /**
      * An internal callback (from InputMethodManagerService) to notify a state change regarding
      * whether the back key should dismiss the software keyboard (IME) or not.
      *
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 5981ab0..5adc248 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -49,6 +49,7 @@
 import android.util.Slog;
 import android.util.StatsLog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -75,7 +76,8 @@
  * tell the system when we go to sleep so that it can lock the keyguard if needed.
  * </p>
  */
-final class Notifier {
+@VisibleForTesting
+public class Notifier {
     private static final String TAG = "PowerManagerNotifier";
 
     private static final boolean DEBUG = false;
@@ -188,6 +190,8 @@
         try {
             mBatteryStats.noteInteractive(true);
         } catch (RemoteException ex) { }
+        StatsLog.write(StatsLog.INTERACTIVE_STATE_CHANGED,
+                StatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON);
     }
 
     /**
@@ -399,6 +403,9 @@
             try {
                 mBatteryStats.noteInteractive(interactive);
             } catch (RemoteException ex) { }
+            StatsLog.write(StatsLog.INTERACTIVE_STATE_CHANGED,
+                    interactive ? StatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON :
+                            StatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF);
 
             // Handle early behaviors.
             mInteractive = interactive;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index bdf12ca..43a9c78 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -64,7 +64,6 @@
 import android.os.WorkSource;
 import android.os.WorkSource.WorkChain;
 import android.provider.Settings;
-import android.provider.Settings.Global;
 import android.provider.Settings.SettingNotFoundException;
 import android.service.dreams.DreamManagerInternal;
 import android.service.vr.IVrManager;
@@ -84,7 +83,6 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.server.EventLogTags;
 import com.android.server.LockGuard;
@@ -230,6 +228,10 @@
     private final BatterySaverController mBatterySaverController;
     private final BatterySaverStateMachine mBatterySaverStateMachine;
     private final BatterySavingStats mBatterySavingStats;
+    private final BinderService mBinderService;
+    private final LocalService mLocalService;
+    private final NativeWrapper mNativeWrapper;
+    private final Injector mInjector;
 
     private LightsManager mLightsManager;
     private BatteryManagerInternal mBatteryManagerInternal;
@@ -636,10 +638,76 @@
         }
     }
 
+    /**
+     * Wrapper around the static-native methods of PowerManagerService.
+     *
+     * This class exists to allow us to mock static native methods in our tests. If mocking static
+     * methods becomes easier than this in the future, we can delete this class.
+     */
+    @VisibleForTesting
+    public static class NativeWrapper {
+        /** Wrapper for PowerManager.nativeInit */
+        public void nativeInit(PowerManagerService service) {
+            service.nativeInit();
+        }
+
+        /** Wrapper for PowerManager.nativeAcquireSuspectBlocker */
+        public void nativeAcquireSuspendBlocker(String name) {
+            PowerManagerService.nativeAcquireSuspendBlocker(name);
+        }
+
+        /** Wrapper for PowerManager.nativeReleaseSuspendBlocker */
+        public void nativeReleaseSuspendBlocker(String name) {
+            PowerManagerService.nativeReleaseSuspendBlocker(name);
+        }
+
+        /** Wrapper for PowerManager.nativeSetInteractive */
+        public void nativeSetInteractive(boolean enable) {
+            PowerManagerService.nativeSetInteractive(enable);
+        }
+
+        /** Wrapper for PowerManager.nativeSetAutoSuspend */
+        public void nativeSetAutoSuspend(boolean enable) {
+            PowerManagerService.nativeSetAutoSuspend(enable);
+        }
+
+        /** Wrapper for PowerManager.nativeSendPowerHint */
+        public void nativeSendPowerHint(int hintId, int data) {
+            PowerManagerService.nativeSendPowerHint(hintId, data);
+        }
+
+        /** Wrapper for PowerManager.nativeSetFeature */
+        public void nativeSetFeature(int featureId, int data) {
+            PowerManagerService.nativeSetFeature(featureId, data);
+        }
+    }
+
+    @VisibleForTesting
+    static class Injector {
+        Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
+                SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
+            return new Notifier(looper, context, batteryStats, suspendBlocker, policy);
+        }
+
+        SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
+            SuspendBlocker suspendBlocker = service.new SuspendBlockerImpl(name);
+            service.mSuspendBlockers.add(suspendBlocker);
+            return suspendBlocker;
+        }
+
+        BatterySaverPolicy createBatterySaverPolicy(
+                Object lock, Context context, BatterySavingStats batterySavingStats) {
+            return new BatterySaverPolicy(lock, context, batterySavingStats);
+        }
+
+        NativeWrapper createNativeWrapper() {
+            return new NativeWrapper();
+        }
+    }
+
     final Constants mConstants;
 
     private native void nativeInit();
-
     private static native void nativeAcquireSuspendBlocker(String name);
     private static native void nativeReleaseSuspendBlocker(String name);
     private static native void nativeSetInteractive(boolean enable);
@@ -648,8 +716,19 @@
     private static native void nativeSetFeature(int featureId, int data);
 
     public PowerManagerService(Context context) {
+        this(context, new Injector());
+    }
+
+    @VisibleForTesting
+    PowerManagerService(Context context, Injector injector) {
         super(context);
+
         mContext = context;
+        mBinderService = new BinderService();
+        mLocalService = new LocalService();
+        mNativeWrapper = injector.createNativeWrapper();
+        mInjector = injector;
+
         mHandlerThread = new ServiceThread(TAG,
                 Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
         mHandlerThread.start();
@@ -658,57 +737,40 @@
         mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
 
         mBatterySavingStats = new BatterySavingStats(mLock);
-        mBatterySaverPolicy = new BatterySaverPolicy(mLock, mContext, mBatterySavingStats);
+        mBatterySaverPolicy =
+                mInjector.createBatterySaverPolicy(mLock, mContext, mBatterySavingStats);
         mBatterySaverController = new BatterySaverController(mLock, mContext,
-                BackgroundThread.get().getLooper(), mBatterySaverPolicy, mBatterySavingStats);
+                BackgroundThread.get().getLooper(), mBatterySaverPolicy,
+                mBatterySavingStats);
         mBatterySaverStateMachine = new BatterySaverStateMachine(
                 mLock, mContext, mBatterySaverController);
 
         synchronized (mLock) {
-            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
-            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
-            mDisplaySuspendBlocker.acquire();
-            mHoldingDisplaySuspendBlocker = true;
+            mWakeLockSuspendBlocker =
+                    mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks");
+            mDisplaySuspendBlocker =
+                    mInjector.createSuspendBlocker(this, "PowerManagerService.Display");
+            if (mDisplaySuspendBlocker != null) {
+                mDisplaySuspendBlocker.acquire();
+                mHoldingDisplaySuspendBlocker = true;
+            }
             mHalAutoSuspendModeEnabled = false;
             mHalInteractiveModeEnabled = true;
 
             mWakefulness = WAKEFULNESS_AWAKE;
-
             sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
 
-            nativeInit();
-            nativeSetAutoSuspend(false);
-            nativeSetInteractive(true);
-            nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
+            mNativeWrapper.nativeInit(this);
+            mNativeWrapper.nativeSetAutoSuspend(false);
+            mNativeWrapper.nativeSetInteractive(true);
+            mNativeWrapper.nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
         }
     }
 
-    @VisibleForTesting
-    PowerManagerService(Context context, BatterySaverPolicy batterySaverPolicy) {
-        super(context);
-
-        mContext = context;
-        mHandlerThread = new ServiceThread(TAG,
-                Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
-        mHandlerThread.start();
-        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
-        mConstants = new Constants(mHandler);
-        mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
-        mDisplaySuspendBlocker = null;
-        mWakeLockSuspendBlocker = null;
-
-        mBatterySavingStats = new BatterySavingStats(mLock);
-        mBatterySaverPolicy = batterySaverPolicy;
-        mBatterySaverController = new BatterySaverController(mLock, context,
-                BackgroundThread.getHandler().getLooper(), batterySaverPolicy, mBatterySavingStats);
-        mBatterySaverStateMachine = new BatterySaverStateMachine(
-                mLock, mContext, mBatterySaverController);
-    }
-
     @Override
     public void onStart() {
-        publishBinderService(Context.POWER_SERVICE, new BinderService());
-        publishLocalService(PowerManagerInternal.class, new LocalService());
+        publishBinderService(Context.POWER_SERVICE, mBinderService);
+        publishLocalService(PowerManagerInternal.class, mLocalService);
 
         Watchdog.getInstance().addMonitor(this);
         Watchdog.getInstance().addThread(mHandler);
@@ -752,11 +814,13 @@
             // The notifier runs on the system server's main looper so as not to interfere
             // with the animations and other critical functions of the power manager.
             mBatteryStats = BatteryStatsService.getService();
-            mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
-                    createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy);
+            mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
+                    mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
+                    mPolicy);
 
             mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
-                    createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
+                    mInjector.createSuspendBlocker(
+                            this, "PowerManagerService.WirelessChargerDetector"),
                     mHandler);
             mSettingsObserver = new SettingsObserver(mHandler);
 
@@ -824,7 +888,7 @@
         resolver.registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.DEVICE_DEMO_MODE),
                 false, mSettingsObserver, UserHandle.USER_SYSTEM);
-        IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
+        IVrManager vrManager = IVrManager.Stub.asInterface(getBinderService(Context.VR_SERVICE));
         if (vrManager != null) {
             try {
                 vrManager.registerListener(mVrStateCallbacks);
@@ -927,7 +991,8 @@
                             UserHandle.USER_CURRENT) != 0;
             if (doubleTapWakeEnabled != mDoubleTapWakeEnabled) {
                 mDoubleTapWakeEnabled = doubleTapWakeEnabled;
-                nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0);
+                mNativeWrapper.nativeSetFeature(
+                        POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0);
             }
         }
 
@@ -1014,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);
@@ -1509,6 +1595,11 @@
         }
     }
 
+    @VisibleForTesting
+    int getWakefulness() {
+        return mWakefulness;
+    }
+
     /**
      * Logs the time the device would have spent awake before user activity timeout,
      * had the system not been told the user was inactive.
@@ -2640,7 +2731,7 @@
             mHalAutoSuspendModeEnabled = enable;
             Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalAutoSuspend(" + enable + ")");
             try {
-                nativeSetAutoSuspend(enable);
+                mNativeWrapper.nativeSetAutoSuspend(enable);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_POWER);
             }
@@ -2655,7 +2746,7 @@
             mHalInteractiveModeEnabled = enable;
             Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalInteractive(" + enable + ")");
             try {
-                nativeSetInteractive(enable);
+                mNativeWrapper.nativeSetInteractive(enable);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_POWER);
             }
@@ -3127,7 +3218,7 @@
                 break;
         }
 
-        nativeSendPowerHint(hintId, data);
+        mNativeWrapper.nativeSendPowerHint(hintId, data);
     }
 
     /**
@@ -3718,12 +3809,6 @@
         proto.flush();
     }
 
-    private SuspendBlocker createSuspendBlockerLocked(String name) {
-        SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
-        mSuspendBlockers.add(suspendBlocker);
-        return suspendBlocker;
-    }
-
     private void incrementBootCount() {
         synchronized (mLock) {
             int count;
@@ -4022,7 +4107,7 @@
                     Slog.wtf(TAG, "Suspend blocker \"" + mName
                             + "\" was finalized without being released!");
                     mReferenceCount = 0;
-                    nativeReleaseSuspendBlocker(mName);
+                    mNativeWrapper.nativeReleaseSuspendBlocker(mName);
                     Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
                 }
             } finally {
@@ -4039,7 +4124,7 @@
                         Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
                     }
                     Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
-                    nativeAcquireSuspendBlocker(mName);
+                    mNativeWrapper.nativeAcquireSuspendBlocker(mName);
                 }
             }
         }
@@ -4052,7 +4137,7 @@
                     if (DEBUG_SPEW) {
                         Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
                     }
-                    nativeReleaseSuspendBlocker(mName);
+                    mNativeWrapper.nativeReleaseSuspendBlocker(mName);
                     Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
                 } else if (mReferenceCount < 0) {
                     Slog.wtf(TAG, "Suspend blocker \"" + mName
@@ -4090,7 +4175,8 @@
         }
     }
 
-    private final class BinderService extends IPowerManager.Stub {
+    @VisibleForTesting
+    final class BinderService extends IPowerManager.Stub {
         @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out,
                 FileDescriptor err, String[] args, ShellCallback callback,
@@ -4339,8 +4425,11 @@
 
         @Override // Binder call
         public boolean setPowerSaveMode(boolean enabled) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.DEVICE_POWER, null);
+            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER)
+                    != PackageManager.PERMISSION_GRANTED) {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.DEVICE_POWER, null);
+            }
             final long ident = Binder.clearCallingIdentity();
             try {
                 return setLowPowerModeInternal(enabled);
@@ -4592,6 +4681,16 @@
     }
 
     @VisibleForTesting
+    BinderService getBinderServiceInstance() {
+        return mBinderService;
+    }
+
+    @VisibleForTesting
+    LocalService getLocalServiceInstance() {
+        return mLocalService;
+    }
+
+    @VisibleForTesting
     // lastRebootReasonProperty argument to permit testing
     int getLastShutdownReasonInternal(String lastRebootReasonProperty) {
         String line = SystemProperties.get(lastRebootReasonProperty);
diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/services/core/java/com/android/server/security/VerityUtils.java
index 180f343..8070f3a 100644
--- a/services/core/java/com/android/server/security/VerityUtils.java
+++ b/services/core/java/com/android/server/security/VerityUtils.java
@@ -23,45 +23,79 @@
 import android.os.SharedMemory;
 import android.system.ErrnoException;
 import android.system.Os;
+import android.util.Pair;
+import android.util.Slog;
 import android.util.apk.ApkSignatureVerifier;
 import android.util.apk.ByteBufferFactory;
 import android.util.apk.SignatureNotFoundException;
-import android.util.Pair;
-import android.util.Slog;
+import android.util.apk.VerityBuilder;
+
+import libcore.util.HexEncoding;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.DigestException;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 
+import sun.security.pkcs.PKCS7;
+
 /** Provides fsverity related operations. */
 abstract public class VerityUtils {
     private static final String TAG = "VerityUtils";
 
+    /** The maximum size of signature file.  This is just to avoid potential abuse. */
+    private static final int MAX_SIGNATURE_FILE_SIZE_BYTES = 8192;
+
     private static final boolean DEBUG = false;
 
     /**
-     * Generates Merkle tree and fsverity metadata.
+     * Generates Merkle tree and fs-verity metadata.
      *
-     * @return {@code SetupResult} that contains the {@code EsetupResultCode}, and when success, the
+     * @return {@code SetupResult} that contains the result code, and when success, the
      *         {@code FileDescriptor} to read all the data from.
      */
-    public static SetupResult generateApkVeritySetupData(@NonNull String apkPath) {
-        if (DEBUG) Slog.d(TAG, "Trying to install apk verity to " + apkPath);
+    public static SetupResult generateApkVeritySetupData(@NonNull String apkPath,
+            String signaturePath, boolean skipSigningBlock) {
+        if (DEBUG) {
+            Slog.d(TAG, "Trying to install apk verity to " + apkPath + " with signature file "
+                    + signaturePath);
+        }
         SharedMemory shm = null;
         try {
-            byte[] signedRootHash = ApkSignatureVerifier.getVerityRootHash(apkPath);
-            if (signedRootHash == null) {
+            byte[] signedVerityHash;
+            if (skipSigningBlock) {
+                signedVerityHash = ApkSignatureVerifier.getVerityRootHash(apkPath);
+            } else {
+                Path path = Paths.get(signaturePath);
+                if (Files.exists(path)) {
+                    // TODO(112037636): fail early if the signing key is not in .fs-verity keyring.
+                    PKCS7 pkcs7 = new PKCS7(Files.readAllBytes(path));
+                    signedVerityHash = pkcs7.getContentInfo().getContentBytes();
+                    if (DEBUG) {
+                        Slog.d(TAG, "fs-verity measurement = " + bytesToString(signedVerityHash));
+                    }
+                } else {
+                    signedVerityHash = null;
+                }
+            }
+
+            if (signedVerityHash == null) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Skip verity tree generation since there is no root hash");
+                    Slog.d(TAG, "Skip verity tree generation since there is no signed root hash");
                 }
                 return SetupResult.skipped();
             }
 
-            Pair<SharedMemory, Integer> result = generateApkVerityIntoSharedMemory(apkPath,
-                    signedRootHash);
+            Pair<SharedMemory, Integer> result = generateFsVerityIntoSharedMemory(apkPath,
+                    signaturePath, signedVerityHash, skipSigningBlock);
             shm = result.first;
             int contentSize = result.second;
             FileDescriptor rfd = shm.getFileDescriptor();
@@ -81,11 +115,11 @@
     }
 
     /**
-     * {@see ApkSignatureVerifier#generateFsverityRootHash(String)}.
+     * {@see ApkSignatureVerifier#generateApkVerityRootHash(String)}.
      */
-    public static byte[] generateFsverityRootHash(@NonNull String apkPath)
+    public static byte[] generateApkVerityRootHash(@NonNull String apkPath)
             throws NoSuchAlgorithmException, DigestException, IOException {
-        return ApkSignatureVerifier.generateFsverityRootHash(apkPath);
+        return ApkSignatureVerifier.generateApkVerityRootHash(apkPath);
     }
 
     /**
@@ -97,22 +131,114 @@
     }
 
     /**
+     * Generates fs-verity metadata for {@code filePath} in the buffer created by {@code
+     * trackedBufferFactory}. The metadata contains the Merkle tree, fs-verity descriptor and
+     * extensions, including a PKCS#7 signature provided in {@code signaturePath}.
+     *
+     * <p>It is worthy to note that {@code trackedBufferFactory} generates a "tracked" {@code
+     * ByteBuffer}. The data will be used outside this method via the factory itself.
+     *
+     * @return fs-verity measurement of {@code filePath}, which is a SHA-256 of fs-verity descriptor
+     *         and authenticated extensions.
+     */
+    private static byte[] generateFsverityMetadata(String filePath, String signaturePath,
+            @NonNull TrackedShmBufferFactory trackedBufferFactory)
+            throws IOException, SignatureNotFoundException, SecurityException, DigestException,
+                   NoSuchAlgorithmException {
+        try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
+            VerityBuilder.VerityResult result = VerityBuilder.generateFsVerityTree(
+                    file, trackedBufferFactory);
+
+            ByteBuffer buffer = result.verityData;
+            buffer.position(result.merkleTreeSize);
+            return generateFsverityDescriptorAndMeasurement(file, result.rootHash, signaturePath,
+                    buffer);
+        }
+    }
+
+    /**
+     * Generates fs-verity descriptor including the extensions to the {@code output} and returns the
+     * fs-verity measurement.
+     *
+     * @return fs-verity measurement, which is a SHA-256 of fs-verity descriptor and authenticated
+     *         extensions.
+     */
+    private static byte[] generateFsverityDescriptorAndMeasurement(
+            @NonNull RandomAccessFile file, @NonNull byte[] rootHash,
+            @NonNull String pkcs7SignaturePath, @NonNull ByteBuffer output)
+            throws IOException, NoSuchAlgorithmException, DigestException {
+        final short kRootHashExtensionId = 1;
+        final short kPkcs7SignatureExtensionId = 3;
+        final int origPosition = output.position();
+
+        // For generating fs-verity file measurement, which consists of the descriptor and
+        // authenticated extensions (but not unauthenticated extensions and the footer).
+        MessageDigest md = MessageDigest.getInstance("SHA-256");
+
+        // 1. Generate fs-verity descriptor.
+        final byte[] desc = constructFsverityDescriptorNative(file.length());
+        output.put(desc);
+        md.update(desc);
+
+        // 2. Generate authenticated extensions.
+        final byte[] authExt =
+                constructFsverityExtensionNative(kRootHashExtensionId, rootHash.length);
+        output.put(authExt);
+        output.put(rootHash);
+        md.update(authExt);
+        md.update(rootHash);
+
+        // 3. Generate unauthenticated extensions.
+        ByteBuffer header = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);
+        output.putShort((short) 1);  // number of unauthenticated extensions below
+        output.position(output.position() + 6);
+
+        // Generate PKCS#7 extension. NB: We do not verify agaist trusted certificate (should be
+        // done by the caller if needed).
+        Path path = Paths.get(pkcs7SignaturePath);
+        if (Files.size(path) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
+            throw new IllegalArgumentException("Signature size is unexpectedly large: "
+                    + pkcs7SignaturePath);
+        }
+        final byte[] pkcs7Signature = Files.readAllBytes(path);
+        output.put(constructFsverityExtensionNative(kPkcs7SignatureExtensionId,
+                    pkcs7Signature.length));
+        output.put(pkcs7Signature);
+
+        // 4. Generate the footer.
+        output.put(constructFsverityFooterNative(output.position() - origPosition));
+
+        return md.digest();
+    }
+
+    private static native byte[] constructFsverityDescriptorNative(long fileSize);
+    private static native byte[] constructFsverityExtensionNative(short extensionId,
+            int extensionDataSize);
+    private static native byte[] constructFsverityFooterNative(int offsetToDescriptorHead);
+
+    /**
      * Returns a pair of {@code SharedMemory} and {@code Integer}. The {@code SharedMemory} contains
      * Merkle tree and fsverity headers for the given apk, in the form that can immediately be used
      * for fsverity setup. The data is aligned to the beginning of {@code SharedMemory}, and has
      * length equals to the returned {@code Integer}.
      */
-    private static Pair<SharedMemory, Integer> generateApkVerityIntoSharedMemory(
-            String apkPath, byte[] expectedRootHash)
+    private static Pair<SharedMemory, Integer> generateFsVerityIntoSharedMemory(
+            String apkPath, String signaturePath, @NonNull byte[] expectedRootHash,
+            boolean skipSigningBlock)
             throws IOException, SecurityException, DigestException, NoSuchAlgorithmException,
                    SignatureNotFoundException {
         TrackedShmBufferFactory shmBufferFactory = new TrackedShmBufferFactory();
-        byte[] generatedRootHash = ApkSignatureVerifier.generateApkVerity(apkPath,
-                shmBufferFactory);
+        byte[] generatedRootHash;
+        if (skipSigningBlock) {
+            generatedRootHash = ApkSignatureVerifier.generateApkVerity(apkPath, shmBufferFactory);
+        } else {
+            generatedRootHash = generateFsverityMetadata(apkPath, signaturePath, shmBufferFactory);
+        }
         // We only generate Merkle tree once here, so it's important to make sure the root hash
         // matches the signed one in the apk.
         if (!Arrays.equals(expectedRootHash, generatedRootHash)) {
-            throw new SecurityException("Locally generated verity root hash does not match");
+            throw new SecurityException("verity hash mismatch: "
+                    + bytesToString(generatedRootHash) + " != " + bytesToString(expectedRootHash));
         }
 
         int contentSize = shmBufferFactory.getBufferLimit();
@@ -126,11 +252,15 @@
         return Pair.create(shm, contentSize);
     }
 
+    private static String bytesToString(byte[] bytes) {
+        return HexEncoding.encodeToString(bytes);
+    }
+
     public static class SetupResult {
         /** Result code if verity is set up correctly. */
         private static final int RESULT_OK = 1;
 
-        /** Result code if the apk does not contain a verity root hash. */
+        /** Result code if signature is not provided. */
         private static final int RESULT_SKIPPED = 2;
 
         /** Result code if the setup failed. */
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 444ac2c..1abaaf2 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;
@@ -47,6 +49,7 @@
 import android.os.IStoraged;
 import android.os.IThermalEventListener;
 import android.os.IThermalService;
+import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.RemoteException;
@@ -63,10 +66,14 @@
 import android.telephony.ModemActivityInfo;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
+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;
+import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.net.NetworkStatsFactory;
 import com.android.internal.os.BinderCallsStats.ExportedCallStat;
 import com.android.internal.os.KernelCpuSpeedReader;
@@ -78,10 +85,12 @@
 import com.android.internal.os.KernelWakelockStats;
 import com.android.internal.os.LooperStats;
 import com.android.internal.os.PowerProfile;
+import com.android.internal.os.StoragedUidIoStatsReader;
 import com.android.internal.util.DumpUtils;
 import com.android.server.BinderCallsStatsService;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemServiceManager;
 import com.android.server.storage.DiskStatsFileLogger;
 import com.android.server.storage.DiskStatsLoggingService;
 
@@ -95,6 +104,7 @@
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -172,14 +182,18 @@
             new KernelUidCpuActiveTimeReader();
     private KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader =
             new KernelUidCpuClusterTimeReader();
+    private StoragedUidIoStatsReader mStoragedUidIoStatsReader =
+            new StoragedUidIoStatsReader();
 
     private static IThermalService sThermalService;
+    private File mBaseDir =
+            new File(SystemServiceManager.ensureSystemDir(), "stats_companion");
 
     public StatsCompanionService(Context context) {
         super();
         mContext = context;
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-
+        mBaseDir.mkdirs();
         mAppUpdateReceiver = new AppUpdateReceiver();
         mUserUpdateReceiver = new BroadcastReceiver() {
             @Override
@@ -254,34 +268,38 @@
 
     @Override
     public void sendSubscriberBroadcast(IBinder intentSenderBinder, long configUid, long configKey,
-                                        long subscriptionId, long subscriptionRuleId,
-                                        String[] cookies,
-                                        StatsDimensionsValue dimensionsValue) {
+            long subscriptionId, long subscriptionRuleId, String[] cookies,
+            StatsDimensionsValue dimensionsValue) {
         enforceCallingPermission();
         IntentSender intentSender = new IntentSender(intentSenderBinder);
-        Intent intent = new Intent()
-                .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
-                .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configKey)
-                .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId)
-                .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID, subscriptionRuleId)
-                .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue);
+        Intent intent =
+                new Intent()
+                        .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
+                        .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configKey)
+                        .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId)
+                        .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID, subscriptionRuleId)
+                        .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue);
 
         ArrayList<String> cookieList = new ArrayList<>(cookies.length);
-        for (String cookie : cookies) { cookieList.add(cookie); }
+        for (String cookie : cookies) {
+            cookieList.add(cookie);
+        }
         intent.putStringArrayListExtra(
                 StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList);
 
         if (DEBUG) {
-            Slog.d(TAG, String.format(
-                    "Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
-                    configUid, configKey, subscriptionId, subscriptionRuleId,
-                    Arrays.toString(cookies), dimensionsValue));
+            Slog.d(TAG,
+                    String.format("Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
+                            configUid, configKey, subscriptionId, subscriptionRuleId,
+                            Arrays.toString(cookies),
+                            dimensionsValue));
         }
         try {
             intentSender.sendIntent(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null);
         } catch (IntentSender.SendIntentException e) {
-            Slog.w(TAG, "Unable to send using IntentSender from uid " + configUid
-                    + "; presumably it had been cancelled.");
+            Slog.w(TAG,
+                    "Unable to send using IntentSender from uid " + configUid
+                            + "; presumably it had been cancelled.");
         }
     }
 
@@ -318,7 +336,7 @@
         // Add in all the apps for every user/profile.
         for (UserInfo profile : users) {
             List<PackageInfo> pi =
-                pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id);
+                    pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id);
             for (int j = 0; j < pi.size(); j++) {
                 if (pi.get(j).applicationInfo != null) {
                     uids.add(pi.get(j).applicationInfo.uid);
@@ -403,8 +421,9 @@
     public final static class PullingAlarmListener implements OnAlarmListener {
         @Override
         public void onAlarm() {
-            if (DEBUG)
+            if (DEBUG) {
                 Slog.d(TAG, "Time to poll something.");
+            }
             synchronized (sStatsdLock) {
                 if (sStatsd == null) {
                     Slog.w(TAG, "Could not access statsd to inform it of pulling alarm firing.");
@@ -423,8 +442,9 @@
     public final static class PeriodicAlarmListener implements OnAlarmListener {
         @Override
         public void onAlarm() {
-            if (DEBUG)
+            if (DEBUG) {
                 Slog.d(TAG, "Time to trigger periodic alarm.");
+            }
             synchronized (sStatsdLock) {
                 if (sStatsd == null) {
                     Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
@@ -460,7 +480,7 @@
                     return;
                 }
                 try {
-                  sStatsd.informDeviceShutdown();
+                    sStatsd.informDeviceShutdown();
                 } catch (Exception e) {
                     Slog.w(TAG, "Failed to inform statsd of a shutdown event.", e);
                 }
@@ -499,9 +519,11 @@
     @Override // Binder call
     public void setAlarmForSubscriberTriggering(long timestampMs) {
         enforceCallingPermission();
-        if (DEBUG)
-            Slog.d(TAG, "Setting periodic alarm in about " +
-                    (timestampMs - SystemClock.elapsedRealtime()));
+        if (DEBUG) {
+            Slog.d(TAG,
+                    "Setting periodic alarm in about " + (timestampMs
+                            - SystemClock.elapsedRealtime()));
+        }
         final long callingToken = Binder.clearCallingIdentity();
         try {
             // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
@@ -516,8 +538,9 @@
     @Override // Binder call
     public void cancelAlarmForSubscriberTriggering() {
         enforceCallingPermission();
-        if (DEBUG)
+        if (DEBUG) {
             Slog.d(TAG, "Cancelling periodic alarm");
+        }
         final long callingToken = Binder.clearCallingIdentity();
         try {
             mAlarmManager.cancel(mPeriodicAlarmListener);
@@ -547,8 +570,9 @@
     @Override // Binder call
     public void cancelPullingAlarm() {
         enforceCallingPermission();
-        if (DEBUG)
+        if (DEBUG) {
             Slog.d(TAG, "Cancelling pulling alarm");
+        }
         final long callingToken = Binder.clearCallingIdentity();
         try {
             mAlarmManager.cancel(mPullingAlarmListener);
@@ -561,10 +585,11 @@
             int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG) {
         int size = stats.size();
         long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+        long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
         NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
         for (int j = 0; j < size; j++) {
             stats.getValues(j, entry);
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tag, withFGBG ? 6 : 5);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tag, elapsedNanos, wallClockNanos);
             e.writeInt(entry.uid);
             if (withFGBG) {
                 e.writeInt(entry.set);
@@ -640,14 +665,15 @@
         return null;
     }
 
-    private void pullKernelWakelock(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullKernelWakelock(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         final KernelWakelockStats wakelockStats =
                 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
             String name = ent.getKey();
             KernelWakelockStats.Entry kws = ent.getValue();
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 4);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeString(name);
             e.writeInt(kws.mCount);
             e.writeInt(kws.mVersion);
@@ -656,7 +682,9 @@
         }
     }
 
-    private void pullWifiBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullWifiBytesTransfer(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
         try {
             // TODO: Consider caching the following call to get BatteryStatsInternal.
@@ -668,7 +696,8 @@
             NetworkStatsFactory nsf = new NetworkStatsFactory();
             // Combine all the metrics per Uid into one record.
             NetworkStats stats =
-                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)
+                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE,
+                            null)
                             .groupedByUid();
             addNetworkStats(tagId, pulledData, stats, false);
         } catch (java.io.IOException e) {
@@ -678,7 +707,9 @@
         }
     }
 
-    private void pullWifiBytesTransferByFgBg(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullWifiBytesTransferByFgBg(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
         try {
             BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
@@ -688,7 +719,8 @@
             }
             NetworkStatsFactory nsf = new NetworkStatsFactory();
             NetworkStats stats = rollupNetworkStatsByFGBG(
-                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null));
+                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE,
+                            null));
             addNetworkStats(tagId, pulledData, stats, true);
         } catch (java.io.IOException e) {
             Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e);
@@ -697,7 +729,9 @@
         }
     }
 
-    private void pullMobileBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullMobileBytesTransfer(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
         try {
             BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
@@ -708,7 +742,8 @@
             NetworkStatsFactory nsf = new NetworkStatsFactory();
             // Combine all the metrics per Uid into one record.
             NetworkStats stats =
-                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)
+                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE,
+                            null)
                             .groupedByUid();
             addNetworkStats(tagId, pulledData, stats, false);
         } catch (java.io.IOException e) {
@@ -718,12 +753,14 @@
         }
     }
 
-    private void pullBluetoothBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullBluetoothBytesTransfer(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         BluetoothActivityEnergyInfo info = pullBluetoothData();
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         if (info.getUidTraffic() != null) {
             for (UidTraffic traffic : info.getUidTraffic()) {
-                StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
+                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                        wallClockNanos);
                 e.writeInt(traffic.getUid());
                 e.writeLong(traffic.getRxBytes());
                 e.writeLong(traffic.getTxBytes());
@@ -732,7 +769,9 @@
         }
     }
 
-    private void pullMobileBytesTransferByFgBg(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullMobileBytesTransferByFgBg(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
         try {
             BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
@@ -742,7 +781,8 @@
             }
             NetworkStatsFactory nsf = new NetworkStatsFactory();
             NetworkStats stats = rollupNetworkStatsByFGBG(
-                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null));
+                    nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE,
+                            null));
             addNetworkStats(tagId, pulledData, stats, true);
         } catch (java.io.IOException e) {
             Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e);
@@ -751,13 +791,15 @@
         }
     }
 
-    private void pullCpuTimePerFreq(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullCpuTimePerFreq(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
             long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
             if (clusterTimeMs != null) {
                 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
-                    StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
+                    StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                            wallClockNanos);
                     e.writeInt(cluster);
                     e.writeInt(speed);
                     e.writeLong(clusterTimeMs[speed]);
@@ -767,10 +809,11 @@
         }
     }
 
-    private void pullKernelUidCpuTime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullKernelUidCpuTime(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         mKernelUidCpuTimeReader.readAbsolute((uid, userTimeUs, systemTimeUs) -> {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(uid);
             e.writeLong(userTimeUs);
             e.writeLong(systemTimeUs);
@@ -778,12 +821,14 @@
         });
     }
 
-    private void pullKernelUidCpuFreqTime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullKernelUidCpuFreqTime(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         mKernelUidCpuFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
             for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
-                if(cpuFreqTimeMs[freqIndex] != 0) {
-                    StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
+                if (cpuFreqTimeMs[freqIndex] != 0) {
+                    StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                            wallClockNanos);
                     e.writeInt(uid);
                     e.writeInt(freqIndex);
                     e.writeLong(cpuFreqTimeMs[freqIndex]);
@@ -793,11 +838,13 @@
         });
     }
 
-    private void pullKernelUidCpuClusterTime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullKernelUidCpuClusterTime(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         mKernelUidCpuClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
             for (int i = 0; i < cpuClusterTimesMs.length; i++) {
-                StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
+                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                        wallClockNanos);
                 e.writeInt(uid);
                 e.writeInt(i);
                 e.writeLong(cpuClusterTimesMs[i]);
@@ -806,17 +853,20 @@
         });
     }
 
-    private void pullKernelUidCpuActiveTime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullKernelUidCpuActiveTime(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         mKernelUidCpuActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(uid);
-            e.writeLong((long)cpuActiveTimesMs);
+            e.writeLong((long) cpuActiveTimesMs);
             pulledData.add(e);
         });
     }
 
-    private void pullWifiActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullWifiActivityInfo(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
         if (mWifiManager == null) {
             mWifiManager =
@@ -827,7 +877,8 @@
                 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
                 mWifiManager.requestActivityInfo(wifiReceiver);
                 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
-                StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
+                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                        wallClockNanos);
                 e.writeLong(wifiInfo.getTimeStamp());
                 e.writeInt(wifiInfo.getStackState());
                 e.writeLong(wifiInfo.getControllerTxTimeMillis());
@@ -836,14 +887,18 @@
                 e.writeLong(wifiInfo.getControllerEnergyUsed());
                 pulledData.add(e);
             } catch (RemoteException e) {
-                Slog.e(TAG, "Pulling wifiManager for wifi controller activity energy info has error", e);
+                Slog.e(TAG,
+                        "Pulling wifiManager for wifi controller activity energy info has error",
+                        e);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
     }
 
-    private void pullModemActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullModemActivityInfo(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
         if (mTelephony == null) {
             mTelephony = TelephonyManager.from(mContext);
@@ -852,7 +907,7 @@
             SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
             mTelephony.requestModemActivityInfo(modemReceiver);
             final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
-            StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 10);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeLong(modemInfo.getTimestamp());
             e.writeLong(modemInfo.getSleepTimeMillis());
             e.writeLong(modemInfo.getIdleTimeMillis());
@@ -867,9 +922,11 @@
         }
     }
 
-    private void pullBluetoothActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullBluetoothActivityInfo(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         BluetoothActivityEnergyInfo info = pullBluetoothData();
-        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeLong(info.getTimeStamp());
         e.writeInt(info.getBluetoothStackState());
         e.writeLong(info.getControllerTxTimeMillis());
@@ -882,7 +939,8 @@
     private synchronized BluetoothActivityEnergyInfo pullBluetoothData() {
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null) {
-            SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver("bluetooth");
+            SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
+                    "bluetooth");
             adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
             return awaitControllerInfo(bluetoothReceiver);
         } else {
@@ -891,25 +949,29 @@
         }
     }
 
-    private void pullSystemElapsedRealtime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1);
+    private void pullSystemElapsedRealtime(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeLong(SystemClock.elapsedRealtime());
         pulledData.add(e);
     }
 
-    private void pullSystemUpTime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1);
+    private void pullSystemUpTime(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeLong(SystemClock.uptimeMillis());
         pulledData.add(e);
     }
 
-    private void pullProcessMemoryState(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullProcessMemoryState(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         List<ProcessMemoryState> processMemoryStates =
-                LocalServices.getService(ActivityManagerInternal.class)
-                        .getMemoryStateForProcesses();
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+                LocalServices.getService(
+                        ActivityManagerInternal.class).getMemoryStateForProcesses();
         for (ProcessMemoryState processMemoryState : processMemoryStates) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 8 /* fields */);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(processMemoryState.uid);
             e.writeString(processMemoryState.processName);
             e.writeInt(processMemoryState.oomScore);
@@ -918,11 +980,14 @@
             e.writeLong(processMemoryState.rssInBytes);
             e.writeLong(processMemoryState.cacheInBytes);
             e.writeLong(processMemoryState.swapInBytes);
+            e.writeLong(processMemoryState.rssHighWatermarkInBytes);
             pulledData.add(e);
         }
     }
 
-    private void pullBinderCallsStats(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullBinderCallsStats(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         BinderCallsStatsService.Internal binderStats =
                 LocalServices.getService(BinderCallsStatsService.Internal.class);
         if (binderStats == null) {
@@ -931,9 +996,8 @@
 
         List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
         binderStats.reset();
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (ExportedCallStat callStat : callStats) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 13 /* fields */);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(callStat.uid);
             e.writeString(callStat.className);
             e.writeString(callStat.methodName);
@@ -951,7 +1015,9 @@
         }
     }
 
-    private void pullBinderCallsStatsExceptions(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullBinderCallsStatsExceptions(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         BinderCallsStatsService.Internal binderStats =
                 LocalServices.getService(BinderCallsStatsService.Internal.class);
         if (binderStats == null) {
@@ -961,16 +1027,16 @@
         ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
         // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
         // can reset the exception stats.
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (Entry<String, Integer> entry : exceptionStats.entrySet()) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeString(entry.getKey());
             e.writeInt(entry.getValue());
             pulledData.add(e);
         }
     }
 
-    private void pullLooperStats(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         LooperStats looperStats = LocalServices.getService(LooperStats.class);
         if (looperStats == null) {
             return;
@@ -978,10 +1044,9 @@
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
         looperStats.reset();
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (LooperStats.ExportedEntry entry : entries) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 10 /* fields */);
-            e.writeInt(1000); // uid collection not implemented yet
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+            e.writeInt(entry.workSourceUid);
             e.writeString(entry.handlerClassName);
             e.writeString(entry.threadName);
             e.writeString(entry.messageName);
@@ -995,7 +1060,8 @@
         }
     }
 
-    private void pullDiskStats(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         // Run a quick-and-dirty performance test: write 512 bytes
         byte[] junk = new byte[512];
         for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
@@ -1042,41 +1108,40 @@
         }
 
         // Add info pulledData.
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
-        StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeLong(latency);
         e.writeBoolean(fileBased);
         e.writeInt(writeSpeed);
         pulledData.add(e);
     }
 
-    private void pullDirectoryUsage(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
         StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
         StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
 
-        StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA);
         e.writeLong(statFsData.getAvailableBytes());
         e.writeLong(statFsData.getTotalBytes());
         pulledData.add(e);
 
-        e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+        e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE);
         e.writeLong(statFsCache.getAvailableBytes());
         e.writeLong(statFsCache.getTotalBytes());
         pulledData.add(e);
 
-        e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+        e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM);
         e.writeLong(statFsSystem.getAvailableBytes());
         e.writeLong(statFsSystem.getTotalBytes());
         pulledData.add(e);
     }
 
-    private void pullAppSize(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullAppSize(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         try {
             String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
             JSONObject json = new JSONObject(jsonStr);
@@ -1094,7 +1159,7 @@
             }
             for (int i = 0; i < length; i++) {
                 StatsLogEventWrapper e =
-                        new StatsLogEventWrapper(elapsedNanos, tagId, 5 /* fields */);
+                        new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
                 e.writeString(pkg_names.getString(i));
                 e.writeLong(app_sizes.optLong(i, -1L));
                 e.writeLong(app_data_sizes.optLong(i, -1L));
@@ -1107,62 +1172,62 @@
         }
     }
 
-    private void pullCategorySize(int tagId, List<StatsLogEventWrapper> pulledData) {
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+    private void pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         try {
             String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
             JSONObject json = new JSONObject(jsonStr);
             long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
 
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE);
             e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE);
             e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE);
             e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS);
             e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS);
             e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO);
             e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS);
             e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM);
             e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L));
             e.writeLong(cacheTime);
             pulledData.add(e);
 
-            e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */);
+            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER);
             e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L));
             e.writeLong(cacheTime);
@@ -1172,7 +1237,8 @@
         }
     }
 
-    private void pullNumFingerprints(int tagId, List<StatsLogEventWrapper> pulledData) {
+    private void pullNumFingerprints(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
         FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class);
         if (fingerprintManager == null) {
             return;
@@ -1182,11 +1248,10 @@
             return;
         }
         final long token = Binder.clearCallingIdentity();
-        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (UserInfo user : userManager.getUsers()) {
             final int userId = user.getUserHandle().getIdentifier();
             final int numFingerprints = fingerprintManager.getEnrolledFingerprints(userId).size();
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(userId);
             e.writeInt(numFingerprints);
             pulledData.add(e);
@@ -1194,114 +1259,252 @@
         Binder.restoreCallingIdentity(token);
     }
 
+    // read high watermark for section
+    private long readProcStatsHighWaterMark(int section) {
+        try {
+            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().split("_")[1]);
+        } catch (SecurityException e) {
+            Log.e(TAG, "Failed to get procstats high watermark file.", e);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "Failed to parse file name.", e);
+        }
+        return 0;
+    }
+
+    private IProcessStats mProcessStats =
+            IProcessStats.Stub.asInterface(ServiceManager.getService(ProcessStats.SERVICE_NAME));
+
+    private void pullProcessStats(int section, int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        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);
+        }
+    }
+
+    static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
+        int pos = 0;
+        final int initialAvail = stream.available();
+        byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
+        while (true) {
+            int amt = stream.read(data, pos, data.length - pos);
+            if (DEBUG) {
+                Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
+            }
+            if (amt < 0) {
+                if (DEBUG) {
+                    Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
+                }
+                outLen[0] = pos;
+                return data;
+            }
+            pos += amt;
+            if (pos >= data.length) {
+                byte[] newData = new byte[pos + 16384];
+                if (DEBUG) {
+                    Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
+                }
+                System.arraycopy(data, 0, newData, 0, pos);
+                data = newData;
+            }
+        }
+    }
+
+    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);
+            e.writeInt(uid);
+            e.writeLong(fgCharsRead);
+            e.writeLong(fgCharsWrite);
+            e.writeLong(fgBytesRead);
+            e.writeLong(fgBytesWrite);
+            e.writeLong(bgCharsRead);
+            e.writeLong(bgCharsWrite);
+            e.writeLong(bgBytesRead);
+            e.writeLong(bgBytesWrite);
+            e.writeLong(fgFsync);
+            e.writeLong(bgFsync);
+            pulledData.add(e);
+        });
+    }
+
     /**
      * Pulls various data.
      */
     @Override // Binder call
     public StatsLogEventWrapper[] pullData(int tagId) {
         enforceCallingPermission();
-        if (DEBUG)
+        if (DEBUG) {
             Slog.d(TAG, "Pulling " + tagId);
+        }
         List<StatsLogEventWrapper> ret = new ArrayList<>();
+        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+        long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
         switch (tagId) {
             case StatsLog.WIFI_BYTES_TRANSFER: {
-                pullWifiBytesTransfer(tagId, ret);
+                pullWifiBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.MOBILE_BYTES_TRANSFER: {
-                pullMobileBytesTransfer(tagId, ret);
+                pullMobileBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: {
-                pullWifiBytesTransferByFgBg(tagId, ret);
+                pullWifiBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: {
-                pullMobileBytesTransferByFgBg(tagId, ret);
+                pullMobileBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.BLUETOOTH_BYTES_TRANSFER: {
-                pullBluetoothBytesTransfer(tagId, ret);
+                pullBluetoothBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.KERNEL_WAKELOCK: {
-                pullKernelWakelock(tagId, ret);
+                pullKernelWakelock(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.CPU_TIME_PER_FREQ: {
-                pullCpuTimePerFreq(tagId, ret);
+                pullCpuTimePerFreq(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.CPU_TIME_PER_UID: {
-                pullKernelUidCpuTime(tagId, ret);
+                pullKernelUidCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.CPU_TIME_PER_UID_FREQ: {
-                pullKernelUidCpuFreqTime(tagId, ret);
+                pullKernelUidCpuFreqTime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.CPU_CLUSTER_TIME: {
-                pullKernelUidCpuClusterTime(tagId, ret);
+                pullKernelUidCpuClusterTime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.CPU_ACTIVE_TIME: {
-                pullKernelUidCpuActiveTime(tagId, ret);
+                pullKernelUidCpuActiveTime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.WIFI_ACTIVITY_INFO: {
-                pullWifiActivityInfo(tagId, ret);
+                pullWifiActivityInfo(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.MODEM_ACTIVITY_INFO: {
-                pullModemActivityInfo(tagId, ret);
+                pullModemActivityInfo(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.BLUETOOTH_ACTIVITY_INFO: {
-                pullBluetoothActivityInfo(tagId, ret);
+                pullBluetoothActivityInfo(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.SYSTEM_UPTIME: {
-                pullSystemUpTime(tagId, ret);
+                pullSystemUpTime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.SYSTEM_ELAPSED_REALTIME: {
-                pullSystemElapsedRealtime(tagId, ret);
+                pullSystemElapsedRealtime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.PROCESS_MEMORY_STATE: {
-                pullProcessMemoryState(tagId, ret);
+                pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.BINDER_CALLS: {
-                pullBinderCallsStats(tagId, ret);
+                pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.BINDER_CALLS_EXCEPTIONS: {
-                pullBinderCallsStatsExceptions(tagId, ret);
+                pullBinderCallsStatsExceptions(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.LOOPER_STATS: {
-                pullLooperStats(tagId, ret);
+                pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.DISK_STATS: {
-                pullDiskStats(tagId, ret);
+                pullDiskStats(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.DIRECTORY_USAGE: {
-                pullDirectoryUsage(tagId, ret);
+                pullDirectoryUsage(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.APP_SIZE: {
-                pullAppSize(tagId, ret);
+                pullAppSize(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.CATEGORY_SIZE: {
-                pullCategorySize(tagId, ret);
+                pullCategorySize(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
             case StatsLog.NUM_FINGERPRINTS: {
-                pullNumFingerprints(tagId, ret);
+                pullNumFingerprints(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
+            case StatsLog.PROC_STATS: {
+                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;
             }
             default:
@@ -1314,13 +1517,13 @@
     @Override // Binder call
     public void statsdReady() {
         enforceCallingPermission();
-        if (DEBUG) Slog.d(TAG, "learned that statsdReady");
+        if (DEBUG) {
+            Slog.d(TAG, "learned that statsdReady");
+        }
         sayHiToStatsd(); // tell statsd that we're ready too and link to it
-        mContext.sendBroadcastAsUser(
-                new Intent(StatsManager.ACTION_STATSD_STARTED)
+        mContext.sendBroadcastAsUser(new Intent(StatsManager.ACTION_STATSD_STARTED)
                         .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND),
-                UserHandle.SYSTEM,
-                android.Manifest.permission.DUMP);
+                UserHandle.SYSTEM, android.Manifest.permission.DUMP);
     }
 
     @Override
@@ -1365,7 +1568,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);
@@ -1390,18 +1594,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");
@@ -1419,10 +1627,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);
@@ -1436,7 +1646,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);
@@ -1498,7 +1709,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");
             }
@@ -1506,14 +1718,16 @@
                     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));
             }
         }
     }
 
     // Thermal event received from vendor thermal management subsystem
     private static final class ThermalEventListener extends IThermalEventListener.Stub {
-        @Override public void notifyThrottling(boolean isThrottling, Temperature temp) {
+        @Override
+        public void notifyThrottling(boolean isThrottling, Temperature temp) {
             StatsLog.write(StatsLog.THERMAL_THROTTLING, temp.getType(),
                     isThrottling ? 1 : 0, temp.getValue());
         }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index c2d8188..79eab6b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -565,11 +565,12 @@
     }
 
     @Override
-    public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type) {
+    public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type,
+            boolean requireConfirmation) {
         enforceBiometricDialog();
         if (mBar != null) {
             try {
-                mBar.showBiometricDialog(bundle, receiver, type);
+                mBar.showBiometricDialog(bundle, receiver, type, requireConfirmation);
             } catch (RemoteException ex) {
             }
         }
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 83075ed..e5347cf 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -22,17 +22,24 @@
 import android.app.IActivityManager;
 import android.app.IApplicationThread;
 import android.content.ComponentName;
+import android.content.IIntentSender;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.res.CompatibilityInfo;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.SparseIntArray;
-import android.view.RemoteAnimationAdapter;
 
 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.WindowProcessController;
 
+import java.lang.ref.WeakReference;
 import java.util.List;
 
 /**
@@ -177,6 +184,27 @@
             int userId, Intent[] intents, Bundle bOptions);
 
     /**
+     * Start intents as a package.
+     *
+     * @param uid Make a call as if this UID did.
+     * @param callingPackage Make a call as if this package did.
+     * @param intents Intents to start.
+     * @param userId Start the intents on this user.
+     * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
+     * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
+     *        null if not originated by PendingIntent
+     */
+    public abstract int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
+            String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
+            boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent);
+
+    public abstract int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
+            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
+            String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
+            int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
+            PendingIntentRecord originatingPendingIntent);
+
+    /**
      * Start activity {@code intent} without calling user-id check.
      *
      * - DO NOT call it with the calling UID cleared.
@@ -267,6 +295,9 @@
     public abstract void onProcessRemoved(String name, int uid);
     public abstract void onCleanUpApplicationRecord(WindowProcessController proc);
     public abstract int getTopProcessState();
+    public abstract boolean isHeavyWeightProcess(WindowProcessController proc);
+    public abstract void clearHeavyWeightProcessIfEquals(WindowProcessController proc);
+    public abstract void finishHeavyWeightApp();
 
     public abstract boolean isSleeping();
     public abstract boolean isShuttingDown();
@@ -281,4 +312,35 @@
 
     public abstract void onPackageDataCleared(String name);
     public abstract void onPackageUninstalled(String name);
+    public abstract void onPackageAdded(String name, boolean replacing);
+
+    public abstract CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai);
+
+    /**
+     * Set the corresponding display information for the process global configuration. To be called
+     * when we need to show IME on a different display.
+     *
+     * @param pid The process id associated with the IME window.
+     * @param displayId The ID of the display showing the IME.
+     */
+    public abstract void onImeWindowSetOnDisplay(int pid, int displayId);
+
+    public abstract void sendActivityResult(int callingUid, IBinder activityToken,
+            String resultWho, int requestCode, int resultCode, Intent data);
+    public abstract void clearPendingResultForActivity(
+            IBinder activityToken, WeakReference<PendingIntentRecord> pir);
+    public abstract IIntentSender getIntentSender(int type, String packageName,
+            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();
 }
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index 00e3050..be8a0bd 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -35,12 +35,6 @@
     long STATUS_BAR_TRANSITION_DURATION = 120L;
 
     /**
-     * @return Whether we should detach the wallpaper during the animation.
-     * @see Animation#setDetachWallpaper
-     */
-    boolean getDetachWallpaper();
-
-    /**
      * @return Whether we should show the wallpaper during the animation.
      * @see Animation#getShowWallpaper()
      */
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 6da9f10..e57fea3 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -679,11 +679,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 +1065,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
@@ -1632,17 +1645,6 @@
         return null;
     }
 
-    int getLowestAnimLayer() {
-        for (int i = 0; i < mChildren.size(); i++) {
-            final WindowState w = mChildren.get(i);
-            if (w.mRemoved) {
-                continue;
-            }
-            return w.mWinAnimator.mAnimLayer;
-        }
-        return Integer.MAX_VALUE;
-    }
-
     WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
         WindowState candidate = null;
         for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
@@ -1650,8 +1652,7 @@
             if (w.mRemoved) {
                 continue;
             }
-            if (candidate == null || w.mWinAnimator.mAnimLayer >
-                    candidate.mWinAnimator.mAnimLayer) {
+            if (candidate == null) {
                 candidate = w;
             }
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6c7304d..6f728fc 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -70,12 +70,14 @@
 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;
 import static com.android.server.wm.DisplayContentProto.ROTATION;
 import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
 import static com.android.server.wm.DisplayContentProto.STACKS;
+import static com.android.server.wm.DisplayContentProto.SURFACE_SIZE;
 import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
@@ -97,12 +99,17 @@
 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,7 +120,6 @@
 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;
@@ -150,8 +156,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ToBooleanFunction;
-import com.android.internal.view.IInputMethodClient;
 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,6 +449,8 @@
     /** 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.
      */
@@ -439,36 +478,12 @@
             return;
         }
 
-        final int flags = w.mAttrs.flags;
-
-        // If this window is animating, make a note that we have an animating window and take
-        // care of a request to run a detached wallpaper animation.
-        if (winAnimator.isAnimationSet()) {
-            final AnimationAdapter anim = w.getAnimation();
-            if (anim != null) {
-                if ((flags & FLAG_SHOW_WALLPAPER) != 0 && anim.getDetachWallpaper()) {
-                    mTmpWindow = w;
-                }
-                final int color = anim.getBackgroundColor();
-                if (color != 0) {
-                    final TaskStack stack = w.getStack();
-                    if (stack != null) {
-                        stack.setAnimationBackground(winAnimator, color);
-                    }
-                }
-            }
-        }
-
-        // If this window's app token is running a detached wallpaper animation, make a note so
-        // we can ensure the wallpaper is displayed behind it.
-        final AppWindowToken atoken = winAnimator.mWin.mAppToken;
-        final AnimationAdapter animation = atoken != null ? atoken.getAnimation() : null;
-        if (animation != null) {
-            if ((flags & FLAG_SHOW_WALLPAPER) != 0 && animation.getDetachWallpaper()) {
-                mTmpWindow = w;
-            }
-
-            final int color = animation.getBackgroundColor();
+        // If this window is animating, ensure the animation background is set.
+        final AnimationAdapter anim = w.mAppToken != null
+                ? w.mAppToken.getAnimation()
+                : w.getAnimation();
+        if (anim != null) {
+            final int color = anim.getBackgroundColor();
             if (color != 0) {
                 final TaskStack stack = w.getStack();
                 if (stack != null) {
@@ -490,7 +505,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());
 
@@ -572,7 +587,7 @@
             if (!w.mLayoutAttached) {
                 if (mTmpInitial) {
                     //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                    w.mContentChanged = false;
+                    w.resetContentChanged();
                 }
                 if (w.mAttrs.type == TYPE_DREAM) {
                     // Don't layout windows behind a dream, so that if it does stuff like hide
@@ -617,7 +632,7 @@
                     || w.mLayoutNeeded) {
                 if (mTmpInitial) {
                     //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                    w.mContentChanged = false;
+                    w.resetContentChanged();
                 }
                 w.mLayoutNeeded = false;
                 w.prelayout();
@@ -649,8 +664,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;
@@ -700,7 +713,7 @@
         final WindowStateAnimator winAnimator = w.mWinAnimator;
 
         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
-        w.mContentChanged = false;
+        w.resetContentChanged();
 
         // Moved from updateWindowsAndWallpaperLocked().
         if (w.mHasSurface) {
@@ -741,9 +754,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();
@@ -1367,21 +1379,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);
     }
@@ -2094,22 +2097,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);
@@ -2120,12 +2123,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);
@@ -2307,21 +2305,6 @@
         mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
     }
 
-    /**
-     * If a window that has an animation specifying a colored background and the current wallpaper
-     * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
-     * suddenly disappear.
-     */
-    int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
-        final WindowState visibleWallpaper = mBelowAppWindowsContainers.getWindow(
-                w -> w.mIsWallpaper && w.isVisibleNow());
-
-        if (visibleWallpaper != null) {
-            return visibleWallpaper.mWinAnimator.mAnimLayer;
-        }
-        return winAnimator.mAnimLayer;
-    }
-
     void prepareFreezingTaskBounds() {
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
             final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
@@ -2410,6 +2393,10 @@
             screenRotationAnimation.writeToProto(proto, SCREEN_ROTATION_ANIMATION);
         }
         mDisplayFrames.writeToProto(proto, DISPLAY_FRAMES);
+        proto.write(SURFACE_SIZE, mSurfaceSize);
+        if (mFocusedApp != null) {
+            mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
+        }
         proto.end(token);
     }
 
@@ -2450,6 +2437,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) {
@@ -2581,6 +2589,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");
@@ -2651,6 +2785,12 @@
      */
     void setInputMethodWindowLocked(WindowState win) {
         mInputMethodWindow = win;
+        // Update display configuration for IME process.
+        if (mInputMethodWindow != null) {
+            final int imePid = mInputMethodWindow.mSession.mPid;
+            mService.mAtmInternal.onImeWindowSetOnDisplay(imePid,
+                    mInputMethodWindow.getDisplayId());
+        }
         computeImeTarget(true /* updateImeTarget */);
     }
 
@@ -2739,22 +2879,13 @@
                 if (highestTarget != null) {
                     final AppTransition appTransition = mService.mAppTransition;
                     if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
-                            + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
-                            + " layer=" + highestTarget.mWinAnimator.mAnimLayer
-                            + " new layer=" + target.mWinAnimator.mAnimLayer);
+                            + " animating=" + highestTarget.isAnimating());
 
                     if (appTransition.isTransitionSet()) {
                         // If we are currently setting up for an animation, hold everything until we
                         // can find out what will happen.
                         setInputMethodTarget(highestTarget, true);
                         return highestTarget;
-                    } else if (highestTarget.mWinAnimator.isAnimationSet() &&
-                            highestTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer) {
-                        // If the window we are currently targeting is involved with an animation,
-                        // and it is on top of the next target we will be over, then hold off on
-                        // moving until that is done.
-                        setInputMethodTarget(highestTarget, true);
-                        return highestTarget;
                     }
                 }
             }
@@ -2927,29 +3058,19 @@
         return false;
     }
 
-    void updateWindowsForAnimator(WindowAnimator animator) {
-        mTmpWindowAnimator = animator;
+    void updateWindowsForAnimator() {
         forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */);
     }
 
-    void updateWallpaperForAnimator(WindowAnimator animator) {
+    /**
+     * Updates the {@link TaskStack#setAnimationBackground} for all windows.
+     */
+    void updateBackgroundForAnimator() {
         resetAnimationBackgroundAnimator();
-
-        // Used to indicate a detached wallpaper.
-        mTmpWindow = null;
-        mTmpWindowAnimator = animator;
-
         forAllWindows(mUpdateWallpaperForAnimator, true /* traverseTopToBottom */);
-
-        if (animator.mWindowDetachedWallpaper != mTmpWindow) {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from "
-                    + animator.mWindowDetachedWallpaper + " to " + mTmpWindow);
-            animator.mWindowDetachedWallpaper = mTmpWindow;
-            animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
-        }
     }
 
-    boolean inputMethodClientHasFocus(IInputMethodClient client) {
+    boolean isInputMethodClientFocus(int uid, int pid) {
         final WindowState imFocus = computeImeTarget(false /* updateImeTarget */);
         if (imFocus == null) {
             return false;
@@ -2957,21 +3078,17 @@
 
         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);
         }
 
-        final IInputMethodClient imeClient = imFocus.mSession.mClient;
-
         if (DEBUG_INPUT_METHOD) {
-            Slog.i(TAG_WM, "IM target client: " + imeClient);
-            if (imeClient != null) {
-                Slog.i(TAG_WM, "IM target client binder: " + imeClient.asBinder());
-                Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
-            }
+            Slog.i(TAG_WM, "IM target uid/pid: " + imFocus.mSession.mUid
+                    + "/" + imFocus.mSession.mPid);
+            Slog.i(TAG_WM, "Requesting client uid/pid: " + uid + "/" + pid);
         }
 
-        return imeClient != null && imeClient.asBinder() == client.asBinder();
+        return imFocus.mSession.mUid == uid && imFocus.mSession.mPid == pid;
     }
 
     boolean hasSecureWindowOnScreen() {
@@ -3030,7 +3147,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;
@@ -3114,8 +3231,6 @@
             // can now be shown.
             atoken.updateAllDrawn();
         }
-
-        return mTmpApplySurfaceChangesTransactionState.focusDisplayed;
     }
 
     private void updateBounds() {
@@ -3156,6 +3271,10 @@
         }
     }
 
+    int getSurfaceSize() {
+        return mSurfaceSize;
+    }
+
     void performLayout(boolean initial, boolean updateInputWindows) {
         if (!isLayoutNeeded()) {
             return;
@@ -3256,7 +3375,7 @@
         // TODO(b/68392460): We should screenshot Task controls directly
         // but it's difficult at the moment as the Task doesn't have the
         // correct size set.
-        final Bitmap bitmap = SurfaceControl.screenshot(frame, dw, dh, 0, 1, inRotation, rot);
+        final Bitmap bitmap = SurfaceControl.screenshot(frame, dw, dh, inRotation, rot);
         if (bitmap == null) {
             Slog.w(TAG_WM, "Failed to take screenshot");
             return null;
@@ -3365,7 +3484,6 @@
         boolean displayHasContent;
         boolean obscured;
         boolean syswin;
-        boolean focusDisplayed;
         float preferredRefreshRate;
         int preferredModeId;
 
@@ -3373,7 +3491,6 @@
             displayHasContent = false;
             obscured = false;
             syswin = false;
-            focusDisplayed = false;
             preferredRefreshRate = 0;
             preferredModeId = 0;
         }
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/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index ef3a770..15f6938 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();
 
diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
index d89d6f0..77a024c 100644
--- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
@@ -44,11 +44,6 @@
     }
 
     @Override
-    public boolean getDetachWallpaper() {
-        return mSpec.getDetachWallpaper();
-    }
-
-    @Override
     public boolean getShowWallpaper() {
         return mSpec.getShowWallpaper();
     }
@@ -98,13 +93,6 @@
     interface AnimationSpec {
 
         /**
-         * @see AnimationAdapter#getDetachWallpaper
-         */
-        default boolean getDetachWallpaper() {
-            return false;
-        }
-
-        /**
          * @see AnimationAdapter#getShowWallpaper
          */
         default boolean getShowWallpaper() {
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 1eae567..6fef1630 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -20,8 +20,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
+import static android.view.RemoteAnimationTarget.MODE_OPENING;
 import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
-
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.AnimationAdapterProto.REMOTE;
@@ -48,16 +48,13 @@
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
-
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 import com.android.server.input.InputWindowHandle;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 import com.android.server.wm.utils.InsetUtils;
-
 import com.google.android.collect.Sets;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
@@ -93,6 +90,7 @@
 
     // The recents component app token that is shown behind the visibile tasks
     private AppWindowToken mTargetAppToken;
+    private int mTargetActivityType;
     private Rect mMinimizedHomeBounds = new Rect();
 
     // We start the RecentsAnimationController in a pending-start state since we need to wait for
@@ -259,23 +257,37 @@
         mDisplayId = displayId;
     }
 
+    public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) {
+        initialize(mService.mRoot.getDisplayContent(mDisplayId), targetActivityType, recentTaskIds);
+    }
+
     /**
      * Initializes the recents animation controller. This is a separate call from the constructor
      * because it may call cancelAnimation() which needs to properly clean up the controller
      * in the window manager.
      */
-    public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) {
-        // Make leashes for each of the visible tasks and add it to the recents animation to be
-        // started
-        final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
+    @VisibleForTesting
+    void initialize(DisplayContent dc, int targetActivityType, SparseBooleanArray recentTaskIds) {
+        mTargetActivityType = targetActivityType;
+
+        // Make leashes for each of the visible/target tasks and add it to the recents animation to
+        // be started
         final ArrayList<Task> visibleTasks = dc.getVisibleTasks();
+        final TaskStack targetStack = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType);
+        if (targetStack != null) {
+            for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
+                final Task t = targetStack.getChildAt(i);
+                if (!visibleTasks.contains(t)) {
+                    visibleTasks.add(t);
+                }
+            }
+        }
         final int taskCount = visibleTasks.size();
         for (int i = 0; i < taskCount; i++) {
             final Task task = visibleTasks.get(i);
             final WindowConfiguration config = task.getWindowConfiguration();
             if (config.tasksAreFloating()
-                    || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                    || config.getActivityType() == targetActivityType) {
+                    || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                 continue;
             }
             addAnimation(task, !recentTaskIds.get(task.mTaskId));
@@ -586,7 +598,10 @@
             final Rect insets = new Rect();
             mainWindow.getContentInsets(insets);
             InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets());
-            mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash,
+            final int mode = topApp.getActivityType() == mTargetActivityType
+                    ? MODE_OPENING
+                    : MODE_CLOSING;
+            mTarget = new RemoteAnimationTarget(mTask.mTaskId, mode, mCapturedLeash,
                     !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect,
                     insets, mTask.getPrefixOrderIndex(), mPosition, mBounds,
                     mTask.getWindowConfiguration(), mIsRecentTaskInvisible);
@@ -594,11 +609,6 @@
         }
 
         @Override
-        public boolean getDetachWallpaper() {
-            return false;
-        }
-
-        @Override
         public boolean getShowWallpaper() {
             return false;
         }
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 00422e3..8ec0a01 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -325,11 +325,6 @@
         }
 
         @Override
-        public boolean getDetachWallpaper() {
-            return false;
-        }
-
-        @Override
         public boolean getShowWallpaper() {
             return false;
         }
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index d92818a..3fef87d 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,14 +42,13 @@
 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;
 import static com.android.server.wm.WindowManagerService.logSurface;
-import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
@@ -91,7 +91,6 @@
     private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
     private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
 
-    private boolean mWallpaperForceHidingChanged = false;
     private Object mLastWindowFreezeSource = null;
     private Session mHoldScreen = null;
     private float mScreenBrightness = -1;
@@ -126,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();
@@ -155,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) {
@@ -626,18 +646,6 @@
             recentsAnimationController.checkAnimationReady(mWallpaperController);
         }
 
-        if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
-                && !mService.mAppTransition.isReady()) {
-            // At this point, there was a window with a wallpaper that was force hiding other
-            // windows behind it, but now it is going away. This may be simple -- just animate away
-            // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
-            // shown behind something that was hidden.
-            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
-            if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
-                    "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
-        }
-        mWallpaperForceHidingChanged = false;
-
         if (mWallpaperMayChange) {
             if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change!  Adjusting");
             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
@@ -650,7 +658,6 @@
             if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                     false /*updateInputWindows*/)) {
                 updateInputWindowsNeeded = true;
-                defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
             }
         }
 
@@ -660,7 +667,7 @@
                     defaultDisplay.pendingLayoutChanges);
         }
 
-        final ArraySet<DisplayContent> touchExcludeRegionUpdateDisplays = handleResizingWindows();
+        handleResizingWindows();
 
         if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
                 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
@@ -779,17 +786,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.
@@ -822,16 +819,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
@@ -842,12 +833,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) {
@@ -856,15 +843,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;
     }
 
     /**
@@ -961,10 +940,6 @@
             mWallpaperMayChange = true;
             doRequest = true;
         }
-        if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
-            mWallpaperForceHidingChanged = true;
-            doRequest = true;
-        }
         if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
             mOrientationChangeComplete = false;
         } else {
@@ -1022,6 +997,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/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java
index 6f597277..95ca0a6 100644
--- a/services/core/java/com/android/server/wm/SeamlessRotator.java
+++ b/services/core/java/com/android/server/wm/SeamlessRotator.java
@@ -16,12 +16,12 @@
 
 package com.android.server.wm;
 
-import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
 import android.graphics.Matrix;
 import android.view.DisplayInfo;
+import android.view.Surface;
 import android.view.Surface.Rotation;
 import android.view.SurfaceControl.Transaction;
 
@@ -33,10 +33,10 @@
 /**
  * Helper class for seamless rotation.
  *
- * Works by transforming the window token back into the old display rotation.
+ * Works by transforming the {@link WindowState} back into the old display rotation.
  *
- * Uses deferTransactionUntil instead of latching on the buffer size to allow for seamless 180
- * degree rotations.
+ * Uses {@link android.view.SurfaceControl#deferTransactionUntil(Surface, long)} instead of
+ * latching on the buffer size to allow for seamless 180 degree rotations.
  */
 public class SeamlessRotator {
 
@@ -45,7 +45,7 @@
     private final int mOldRotation;
     private final int mNewRotation;
 
-    public SeamlessRotator(int oldRotation, int newRotation, DisplayInfo info) {
+    public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info) {
         mOldRotation = oldRotation;
         mNewRotation = newRotation;
 
@@ -60,11 +60,16 @@
     }
 
     /**
-     * Applies a transform to the window token's surface that undoes the effect of the global
+     * Applies a transform to the {@link WindowState} surface that undoes the effect of the global
      * display rotation.
      */
-    public void unrotate(Transaction transaction, WindowToken token) {
-        transaction.setMatrix(token.getSurfaceControl(), mTransform, mFloat9);
+    public void unrotate(Transaction transaction, WindowState win) {
+        transaction.setMatrix(win.getSurfaceControl(), mTransform, mFloat9);
+
+        // WindowState sets the position of the window so transform the position and update it.
+        final float[] winSurfacePos = {win.mLastSurfacePosition.x, win.mLastSurfacePosition.y};
+        mTransform.mapPoints(winSurfacePos);
+        transaction.setPosition(win.getSurfaceControl(), winSurfacePos[0], winSurfacePos[1]);
     }
 
     /**
@@ -78,27 +83,23 @@
     }
 
     /**
-     * Removes the transform to the window token's surface that undoes the effect of the global
-     * display rotation.
+     * Removes the transform and sets the previously known surface position for {@link WindowState}
+     * surface that undoes the effect of the global display rotation.
      *
-     * Removing the transform and the result of the WindowState's layout are both tied to the
-     * WindowState's next frame, such that they apply at the same time the client draws the
+     * Removing the transform and the result of the {@link WindowState} layout are both tied to the
+     * {@link WindowState} next frame, such that they apply at the same time the client draws the
      * window in the new orientation.
      */
-    public void finish(WindowToken token, WindowState win) {
+    public void finish(WindowState win) {
         mTransform.reset();
-        token.getPendingTransaction().setMatrix(token.mSurfaceControl, mTransform, mFloat9);
+        final Transaction t = win.getPendingTransaction();
+        t.setMatrix(win.mSurfaceControl, mTransform, mFloat9);
+        t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y);
         if (win.mWinAnimator.mSurfaceController != null) {
-            token.getPendingTransaction().deferTransactionUntil(token.mSurfaceControl,
-                    win.mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
-                    win.getFrameNumber());
-            win.getPendingTransaction().deferTransactionUntil(win.mSurfaceControl,
-                    win.mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
-                    win.getFrameNumber());
-            win.getPendingTransaction().deferTransactionUntil(
-                    win.mWinAnimator.mSurfaceController.mSurfaceControl,
-                    win.mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
-                    win.getFrameNumber());
+            t.deferTransactionUntil(win.mSurfaceControl,
+                    win.mWinAnimator.mSurfaceController.getHandle(), win.getFrameNumber());
+            t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl,
+                    win.mWinAnimator.mSurfaceController.getHandle(), win.getFrameNumber());
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index f9a71d3..acc9c03 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -38,7 +38,6 @@
 import android.os.Parcel;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.MergedConfiguration;
@@ -56,10 +55,6 @@
 import android.view.WindowManager;
 
 import com.android.internal.os.logging.MetricsLoggerWrapper;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.server.LocalServices;
-import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.wm.WindowManagerService.H;
 
 import java.io.PrintWriter;
@@ -73,8 +68,6 @@
 class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
     final WindowManagerService mService;
     final IWindowSessionCallback mCallback;
-    final IInputMethodClient mClient;
-    final InputMethodManagerInternal mInputMethodManagerInternal;
     final int mUid;
     final int mPid;
     private final String mStringName;
@@ -95,17 +88,9 @@
     private String mPackageName;
     private String mRelayoutTag;
 
-    public Session(WindowManagerService service, IWindowSessionCallback callback,
-            IInputMethodClient client, IInputContext inputContext) {
+    public Session(WindowManagerService service, IWindowSessionCallback callback) {
         mService = service;
         mCallback = callback;
-        mClient = client;
-        // Depending on the timing when Session object gets called and SystemServer#mFactoryTestMode
-        // this could be null, right?
-        final InputMethodManagerInternal immInternal =
-                LocalServices.getService(InputMethodManagerInternal.class);
-        mInputMethodManagerInternal =
-                immInternal != null ? immInternal : InputMethodManagerInternal.NOP;
         mUid = Binder.getCallingUid();
         mPid = Binder.getCallingPid();
         mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
@@ -134,12 +119,11 @@
         sb.append("}");
         mStringName = sb.toString();
 
-        mInputMethodManagerInternal.addClient(client, inputContext, mUid, mPid);
         try {
-            client.asBinder().linkToDeath(this, 0);
+            mCallback.asBinder().linkToDeath(this, 0);
         } catch (RemoteException e) {
             // The caller has died, so we can just forget about this.
-            mInputMethodManagerInternal.removeClient(client);
+            // Hmmm, should we call killSessionLocked()??
         }
     }
 
@@ -159,9 +143,8 @@
 
     @Override
     public void binderDied() {
-        mInputMethodManagerInternal.removeClient(mClient);
         synchronized(mService.mWindowMap) {
-            mClient.asBinder().unlinkToDeath(this, 0);
+            mCallback.asBinder().unlinkToDeath(this, 0);
             mClientDead = true;
             killSessionLocked();
         }
diff --git a/services/core/java/com/android/server/wm/TEST_MAPPING b/services/core/java/com/android/server/wm/TEST_MAPPING
index c99329a..0c9a14b 100644
--- a/services/core/java/com/android/server/wm/TEST_MAPPING
+++ b/services/core/java/com/android/server/wm/TEST_MAPPING
@@ -21,7 +21,7 @@
           "include-annotation": "android.platform.test.annotations.Presubmit"
         },
         {
-          "exclude-annotation": "android.support.test.filters.FlakyTest"
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
     },
@@ -35,7 +35,7 @@
           "include-annotation": "android.platform.test.annotations.Presubmit"
         },
         {
-          "exclude-annotation": "android.support.test.filters.FlakyTest"
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index eb419c9..6aa0e01 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -29,6 +29,8 @@
 import static com.android.server.wm.TaskProto.DEFER_REMOVAL;
 import static com.android.server.wm.TaskProto.FILLS_PARENT;
 import static com.android.server.wm.TaskProto.ID;
+import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
+import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
 import static com.android.server.wm.TaskProto.TEMP_INSET_BOUNDS;
 import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
@@ -297,6 +299,12 @@
         return boundsChange;
     }
 
+    @Override
+    void onDisplayChanged(DisplayContent dc) {
+        updateSurfaceSize(dc);
+        super.onDisplayChanged(dc);
+    }
+
     /**
      * Sets the bounds used to calculate the insets. See
      * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
@@ -553,9 +561,10 @@
 
     @Override
     public SurfaceControl getAnimationLeashParent() {
-        // Reparent to the animation layer so that we aren't clipped by the non-minimized
-        // stack bounds, currently we only animate the task for the recents animation
-        return getAppAnimationLayer(ANIMATION_LAYER_STANDARD);
+        // Currently, only the recents animation will create animation leashes for tasks. In this
+        // case, reparent the task to the home animation layer while it is being animated to allow
+        // the home activity to reorder the app windows relative to its own.
+        return getAppAnimationLayer(ANIMATION_LAYER_HOME);
     }
 
     boolean isTaskAnimating() {
@@ -703,6 +712,8 @@
         getBounds().writeToProto(proto, BOUNDS);
         mTempInsetBounds.writeToProto(proto, TEMP_INSET_BOUNDS);
         proto.write(DEFER_REMOVAL, mDeferRemoval);
+        proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
+        proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
         proto.end(token);
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 33416f6..b7e37b2 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -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/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 2b84937..00caceb 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1070,11 +1070,8 @@
     }
 
     void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
-        int animLayer = winAnimator.mAnimLayer;
-        if (mAnimationBackgroundAnimator == null
-                || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
+        if (mAnimationBackgroundAnimator == null) {
             mAnimationBackgroundAnimator = winAnimator;
-            animLayer = mDisplayContent.getLayerForAnimationBackground(winAnimator);
             showAnimationSurface(((color >> 24) & 0xff) / 255f);
         }
     }
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/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 3d349ce..a448f97 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -120,13 +120,11 @@
         }
 
         mFindResults.resetTopWallpaper = true;
-        if (w != winAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
+        if (w.mAppToken != null && w.mAppToken.isHidden() && !w.mAppToken.isSelfAnimating()) {
+
             // If this window's app token is hidden and not animating, it is of no interest to us.
-            if (w.mAppToken.isHidden() && !w.mAppToken.isSelfAnimating()) {
-                if (DEBUG_WALLPAPER) Slog.v(TAG,
-                        "Skipping hidden and not animating token: " + w);
-                return false;
-            }
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Skipping hidden and not animating token: " + w);
+            return false;
         }
         if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()
                 + " mDrawState=" + w.mWinAnimator.mDrawState);
@@ -177,7 +175,7 @@
                 && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
             if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
             mFindResults.setWallpaperTarget(w);
-            if (w == mWallpaperTarget && w.mWinAnimator.isAnimationSet()) {
+            if (w == mWallpaperTarget && w.isAnimating()) {
                 // The current wallpaper target is animating, so we'll look behind it for
                 // another possible target and figure out what is going on later.
                 if (DEBUG_WALLPAPER) Slog.v(TAG,
@@ -185,10 +183,6 @@
             }
             // Found a target! End search.
             return true;
-        } else if (w == winAnimator.mWindowDetachedWallpaper) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "Found animating detached wallpaper target win: " + w);
-            mFindResults.setUseTopWallpaperAsTarget(true);
         }
         return false;
     };
@@ -243,7 +237,7 @@
     }
 
     boolean isWallpaperTargetAnimating() {
-        return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimationSet()
+        return mWallpaperTarget != null && mWallpaperTarget.isAnimating()
                 && (mWallpaperTarget.mAppToken == null
                         || !mWallpaperTarget.mAppToken.isWaitingForTransitionStart());
     }
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index ddda027..e15b783 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -138,7 +138,7 @@
             wallpaper.dispatchWallpaperVisibility(visible);
 
             if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
-                    + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
+                    + wallpaper);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
index 825255e..98c77ac 100644
--- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
@@ -72,11 +72,6 @@
     }
 
     @Override
-    public boolean getDetachWallpaper() {
-        return mAnimation.getDetachWallpaper();
-    }
-
-    @Override
     public boolean getShowWallpaper() {
         return mAnimation.getShowWallpaper();
     }
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 793ffce..ad0b8ec 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -58,17 +58,6 @@
     /** Time of current animation step. Reset on each iteration */
     long mCurrentTime;
 
-    boolean mAppWindowAnimating;
-    /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
-     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
-    int mAnimTransactionSequence;
-
-    /** Window currently running an animation that has requested it be detached
-     * from the wallpaper.  This means we need to ensure the wallpaper is
-     * visible behind it in case it animates in a way that would allow it to be
-     * seen. If multiple windows satisfy this, use the lowest window. */
-    WindowState mWindowDetachedWallpaper = null;
-
     int mBulkUpdateParams = 0;
     Object mLastWindowFreezeSource;
 
@@ -191,9 +180,8 @@
 
                     // Update animations of all applications, including those
                     // associated with exiting/removed apps
-                    ++mAnimTransactionSequence;
-                    dc.updateWindowsForAnimator(this);
-                    dc.updateWallpaperForAnimator(this);
+                    dc.updateWindowsForAnimator();
+                    dc.updateBackgroundForAnimator();
                     dc.prepareSurfaces();
                 }
 
@@ -284,9 +272,6 @@
         if ((bulkUpdateParams & WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE) != 0) {
             builder.append(" WALLPAPER_MAY_CHANGE");
         }
-        if ((bulkUpdateParams & WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED) != 0) {
-            builder.append(" FORCE_HIDING_CHANGED");
-        }
         if ((bulkUpdateParams & WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE) != 0) {
             builder.append(" ORIENTATION_CHANGE_COMPLETE");
         }
@@ -317,8 +302,6 @@
         pw.println();
 
         if (dumpAll) {
-            pw.print(prefix); pw.print("mAnimTransactionSequence=");
-                    pw.print(mAnimTransactionSequence);
             pw.print(prefix); pw.print("mCurrentTime=");
                     pw.println(TimeUtils.formatUptime(mCurrentTime));
         }
@@ -327,10 +310,6 @@
                     pw.print(Integer.toHexString(mBulkUpdateParams));
                     pw.println(bulkUpdateParamsToString(mBulkUpdateParams));
         }
-        if (mWindowDetachedWallpaper != null) {
-            pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
-                pw.println(mWindowDetachedWallpaper);
-        }
     }
 
     int getPendingLayoutChanges(final int displayId) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 8e704a8..46999a2 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -20,13 +20,14 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.SurfaceControl.Transaction;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-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.WindowContainerProto.CONFIGURATION_CONTAINER;
 import static com.android.server.wm.WindowContainerProto.ORIENTATION;
 import static com.android.server.wm.WindowContainerProto.SURFACE_ANIMATOR;
 import static com.android.server.wm.WindowContainerProto.VISIBLE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.annotation.CallSuper;
 import android.annotation.IntDef;
@@ -41,10 +42,8 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Builder;
 import android.view.SurfaceSession;
-
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.wm.SurfaceAnimator.Animatable;
-
 import java.io.PrintWriter;
 import java.util.Comparator;
 import java.util.LinkedList;
@@ -70,7 +69,8 @@
 
     /**
      * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME}
-     * activities that happens below all {@link TaskStack}s.
+     * activities and all activities that are being controlled by the recents animation. This
+     * layer is generally below all {@link TaskStack}s.
      */
     static final int ANIMATION_LAYER_HOME = 2;
 
@@ -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
@@ -503,6 +511,24 @@
         }
     }
 
+    /**
+     * Update the surface size when display changed in order to avoid children being bound by the
+     * old display size.
+     *
+     * Note that we don't want to apply this to all layers, but only limiting this to layers that
+     * don't set their own size ({@link Task}, {@link WindowState} and {@link WindowToken}).
+     */
+    void updateSurfaceSize(DisplayContent dc) {
+        if (mSurfaceControl == null) {
+            return;
+        }
+
+        final int newSurfaceSize = dc.getSurfaceSize();
+        if (mSurfaceControl.getWidth() != newSurfaceSize) {
+            getPendingTransaction().setSize(mSurfaceControl, newSurfaceSize, newSurfaceSize);
+        }
+    }
+
     void setWaitingForDrawnIfResizingChanged() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index cbe7d9d..20a874b 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -36,7 +36,6 @@
 import android.graphics.Rect;
 import android.util.proto.ProtoOutputStream;
 import android.view.DisplayCutout;
-import android.view.WindowManager;
 
 import com.android.server.wm.utils.InsetUtils;
 import com.android.server.wm.utils.WmDisplayCutout;
@@ -191,6 +190,10 @@
 
     private final Rect mTmpRect = new Rect();
 
+    private boolean mHasOutsets;
+
+    private boolean mContentChanged;
+
     public WindowFrames() {
     }
 
@@ -237,11 +240,9 @@
      * Calculates the outsets for this windowFrame. The outsets are calculated by the area between
      * the {@link #mOutsetFrame} and the {@link #mContentFrame}. If there are no outsets, then
      * {@link #mOutsets} is set to empty.
-     *
-     * @param hasOutsets Whether this frame has outsets.
      */
-    void calculateOutsets(boolean hasOutsets) {
-        if (hasOutsets) {
+    void calculateOutsets() {
+        if (mHasOutsets) {
             InsetUtils.insetsBetweenFrames(mOutsetFrame, mContentFrame, mOutsets);
         } else {
             mOutsets.setEmpty();
@@ -249,7 +250,8 @@
     }
 
     /**
-     * Calculate the insets for the type {@link WindowManager.LayoutParams#TYPE_DOCK_DIVIDER}
+     * Calculate the insets for the type
+     * {@link android.view.WindowManager.LayoutParams#TYPE_DOCK_DIVIDER}
      *
      * @param cutoutInsets The insets for the cutout.
      */
@@ -367,6 +369,28 @@
         mLastContentInsets.set(-1, -1, -1, -1);
     }
 
+    /**
+     * Sets whether the frame has outsets.
+     */
+    public void setHasOutsets(boolean hasOutsets) {
+        mHasOutsets = hasOutsets;
+    }
+
+    /**
+     * Sets whether the content has changed. This means that either the size or parent frame has
+     * changed.
+     */
+    public void setContentChanged(boolean contentChanged) {
+        mContentChanged = contentChanged;
+    }
+
+    /**
+     * @see #setContentChanged(boolean)
+     */
+    boolean hasContentChanged() {
+        return mContentChanged;
+    }
+
     public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         mParentFrame.writeToProto(proto, PARENT_FRAME);
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 793ce60..b096bf2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ClipData;
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.display.DisplayManagerInternal;
@@ -30,7 +31,6 @@
 import android.view.MagnificationSpec;
 import android.view.WindowInfo;
 
-import com.android.internal.view.IInputMethodClient;
 import com.android.server.input.InputManagerService;
 import com.android.server.policy.WindowManagerPolicy;
 
@@ -340,20 +340,6 @@
     public abstract int getInputMethodWindowVisibleHeight(int displayId);
 
     /**
-      * Saves last input method window for transition.
-      *
-      * Note that it is assumed that this method is called only by InputMethodManagerService.
-      */
-    public abstract void saveLastInputMethodWindowForTransition();
-
-    /**
-     * Clears last input method window for transition.
-     *
-     * Note that it is assumed that this method is called only by InputMethodManagerService.
-     */
-    public abstract void clearLastInputMethodWindowForTransition();
-
-    /**
      * Notifies WindowManagerService that the current IME window status is being changed.
      *
      * <p>Only {@link com.android.server.inputmethod.InputMethodManagerService} is the expected and
@@ -444,12 +430,35 @@
     public abstract boolean isUidFocused(int uid);
 
     /**
-     * Returns {@code true} if a process that is identified by {@code client} has IME focus.
+     * 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
+     * @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 inputMethodClientHasFocus(IInputMethodClient client);
+    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.
      */
     public abstract int getDisplayIdForWindow(IBinder windowToken);
+
+    // TODO: use WindowProcessController once go/wm-unified is done.
+    /**
+     * Notifies the window manager that configuration of the process associated with the input pid
+     * changed.
+     */
+    public abstract void onProcessConfigurationChanged(int pid, Configuration newConfig);
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2ed09ae..e153a1d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -182,6 +182,7 @@
 import android.util.MergedConfiguration;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 import android.util.TimeUtils;
@@ -226,14 +227,13 @@
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IShortcutService;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.LatencyTracker;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
 import com.android.internal.view.WindowManagerPolicyThread;
 import com.android.server.AnimationThread;
 import com.android.server.DisplayThread;
@@ -482,6 +482,10 @@
      */
     WindowState[] mPendingRemoveTmp = new WindowState[20];
 
+    // TODO: use WindowProcessController once go/wm-unified is done.
+    /** Mapping of process pids to configurations */
+    final SparseArray<Configuration> mProcessConfigurations = new SparseArray<>();
+
     /**
      * Windows whose surface should be destroyed.
      */
@@ -495,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.
      */
@@ -635,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;
@@ -717,9 +707,6 @@
         }
     }
 
-    // TODO: Move to RootWindowContainer
-    AppWindowToken mFocusedApp = null;
-
     PowerManager mPowerManager;
     PowerManagerInternal mPowerManagerInternal;
 
@@ -1367,8 +1354,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);
@@ -1378,8 +1365,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)) {
@@ -1411,7 +1398,6 @@
 
             win.mToken.addWindow(win);
             if (type == TYPE_INPUT_METHOD) {
-                win.mGivenInsetsPending = true;
                 displayContent.setInputMethodWindowLocked(win);
                 imMayMove = false;
             } else if (type == TYPE_INPUT_METHOD_DIALOG) {
@@ -1501,7 +1487,7 @@
             win.getParent().assignChildLayers();
 
             if (focusChanged) {
-                displayContent.getInputMonitor().setInputFocusLw(mCurrentFocus,
+                displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus,
                         false /*updateInputWindows*/);
             }
             displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);
@@ -1676,8 +1662,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);
@@ -1713,7 +1700,6 @@
             atoken.postWindowRemoveStartingWindowCleanup(win);
         }
 
-        final DisplayContent dc = win.getDisplayContent();
         if (win.mAttrs.type == TYPE_WALLPAPER) {
             dc.mWallpaperController.clearLastWallpaperTimeoutTime();
             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1975,9 +1961,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;
@@ -2022,8 +2008,7 @@
                 }
                 result |= RELAYOUT_RES_SURFACE_CHANGED;
                 if (!win.mWillReplaceWindow) {
-                    focusMayChange = tryStartExitingAnimation(win, winAnimator, isDefaultDisplay,
-                            focusMayChange);
+                    focusMayChange = tryStartExitingAnimation(win, winAnimator, focusMayChange);
                 }
             }
 
@@ -2048,7 +2033,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
@@ -2196,7 +2181,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;
@@ -2204,9 +2189,9 @@
             transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
         }
         if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
-            focusMayChange = isDefaultDisplay;
+            focusMayChange = true;
             win.mAnimatingExit = true;
-        } else if (win.mWinAnimator.isAnimationSet()) {
+        } else if (win.isAnimating()) {
             // Currently in a hide animation... turn this into
             // an exit.
             win.mAnimatingExit = true;
@@ -2501,57 +2486,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 */);
@@ -2712,6 +2646,11 @@
         }
     }
 
+    @VisibleForTesting
+    void setRecentsAnimationController(RecentsAnimationController controller) {
+        mRecentsAnimationController = controller;
+    }
+
     public RecentsAnimationController getRecentsAnimationController() {
         return mRecentsAnimationController;
     }
@@ -4387,7 +4326,8 @@
     }
 
     private WindowState getFocusedWindowLocked() {
-        return mCurrentFocus;
+        // Return the focused window in the focused display.
+        return mRoot.getTopFocusedDisplayContent().mCurrentFocus;
     }
 
     TaskStack getImeFocusStackLocked() {
@@ -4395,8 +4335,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() {
@@ -4534,7 +4477,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;
@@ -4546,7 +4488,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;
@@ -4593,6 +4534,7 @@
             }
             switch (msg.what) {
                 case REPORT_FOCUS_CHANGE: {
+                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                     WindowState lastFocus;
                     WindowState newFocus;
 
@@ -4600,24 +4542,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;
                         }
                     }
@@ -4628,8 +4568,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);
@@ -4643,15 +4581,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);
@@ -4666,21 +4605,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);
@@ -4833,14 +4757,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);
@@ -5037,12 +4953,8 @@
     // -------------------------------------------------------------
 
     @Override
-    public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
-            IInputContext inputContext) {
-        if (client == null) throw new IllegalArgumentException("null client");
-        if (inputContext == null) throw new IllegalArgumentException("null inputContext");
-        Session session = new Session(this, callback, client, inputContext);
-        return session;
+    public IWindowSession openSession(IWindowSessionCallback callback) {
+        return new Session(this, callback);
     }
 
     @Override
@@ -5075,9 +4987,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
-        }
+
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized(mWindowMap) {
@@ -5110,9 +5020,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
-        }
+
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized(mWindowMap) {
@@ -5192,9 +5100,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
-        }
+
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized(mWindowMap) {
@@ -5241,9 +5147,6 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
-        }
 
         final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser",
@@ -5272,9 +5175,6 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
-        }
 
         final int callingUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, true, "clearForcedDisplayDensityForUser",
@@ -5561,93 +5461,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) {
-                    final int prevImeAnimLayer =
-                            displayContent.mInputMethodWindow.mWinAnimator.mAnimLayer;
-                    displayContent.assignWindowLayers(false /* setLayoutNeeded */);
-                    imWindowChanged |= prevImeAnimLayer
-                            != displayContent.mInputMethodWindow.mWinAnimator.mAnimLayer;
-                }
-            }
-
-            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) {
@@ -5683,11 +5501,6 @@
 
         mInputManagerCallback.freezeInputDispatchingLw();
 
-        // Clear the last input window -- that is just used for
-        // clean transitions between IMEs, and if we are freezing
-        // the screen then the whole world is changing behind the scenes.
-        mPolicy.setLastInputMethodWindowLw(null, null);
-
         if (mAppTransition.isTransitionSet()) {
             mAppTransition.freeze();
         }
@@ -6214,11 +6027,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) {
@@ -6316,23 +6130,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:");
@@ -6361,11 +6158,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);
         }
@@ -6496,11 +6289,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);
@@ -6835,9 +6634,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();
         }
     }
 
@@ -7300,23 +7099,6 @@
         }
 
         @Override
-        public void saveLastInputMethodWindowForTransition() {
-            synchronized (mWindowMap) {
-                final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
-                if (imeWindow != null) {
-                    mPolicy.setLastInputMethodWindowLw(imeWindow, mInputMethodTarget);
-                }
-            }
-        }
-
-        @Override
-        public void clearLastInputMethodWindowForTransition() {
-            synchronized (mWindowMap) {
-                mPolicy.setLastInputMethodWindowLw(null, null);
-            }
-        }
-
-        @Override
         public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
                 boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed) {
             mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed);
@@ -7407,36 +7189,62 @@
         @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;
             }
         }
 
-    public boolean inputMethodClientHasFocus(IInputMethodClient client) {
-        boolean hasFocus;
-        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.inputMethodClientHasFocus(client)) {
+        @Override
+        public boolean isInputMethodClientFocus(int uid, int pid, int displayId) {
+            if (displayId == Display.INVALID_DISPLAY) {
+                return false;
+            }
+            synchronized (mWindowMap) {
+                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,
+                // so let's also look at the current focus.  (An example:
+                // go to Gmail, start searching so the keyboard goes up,
+                // 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.
+                final WindowState currentFocus = displayContent.mCurrentFocus;
+                if (currentFocus != null && currentFocus.mSession.mUid == uid
+                        && currentFocus.mSession.mPid == pid) {
                     return true;
                 }
             }
+            return false;
+        }
 
-            // 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,
-            // so let's also look at the current focus.  (An example:
-            // go to Gmail, start searching so the keyboard goes up,
-            // 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.mClient != null
-                    && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
+        @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);
+            }
         }
-        return false;
-    }
 
         @Override
         public int getDisplayIdForWindow(IBinder windowToken) {
@@ -7448,6 +7256,19 @@
                 return Display.INVALID_DISPLAY;
             }
         }
+
+        @Override
+        public void onProcessConfigurationChanged(int pid, Configuration newConfig) {
+            synchronized (mWindowMap) {
+                Configuration currentConfig = mProcessConfigurations.get(pid);
+                if (currentConfig == null) {
+                    currentConfig = new Configuration(newConfig);
+                } else {
+                    currentConfig.setTo(newConfig);
+                }
+                mProcessConfigurations.put(pid, currentConfig);
+            }
+        }
     }
 
     void registerAppFreezeListener(AppFreezeListener listener) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 6e0ccfd..831418b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -20,7 +20,6 @@
 
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ShellCommand;
 import android.os.UserHandle;
@@ -28,10 +27,6 @@
 import android.view.Display;
 import android.view.IWindowManager;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -87,21 +82,48 @@
         return -1;
     }
 
+    private int getDisplayId(String opt) {
+        int displayId = Display.DEFAULT_DISPLAY;
+        String option = "-d".equals(opt) ? opt : getNextOption();
+        if (option != null && "-d".equals(option)) {
+            try {
+                displayId = Integer.parseInt(getNextArgRequired());
+            } catch (NumberFormatException e) {
+                getErrPrintWriter().println("Error: bad number " + e);
+            } catch (IllegalArgumentException e) {
+                getErrPrintWriter().println("Error: " + e);
+            }
+        }
+        return displayId;
+    }
+
+    private void printInitialDisplaySize(PrintWriter pw , int displayId) {
+        final Point initialSize = new Point();
+        final Point baseSize = new Point();
+
+        try {
+            mInterface.getInitialDisplaySize(displayId, initialSize);
+            mInterface.getBaseDisplaySize(displayId, baseSize);
+            pw.println("Physical size: " + initialSize.x + "x" + initialSize.y);
+            if (!initialSize.equals(baseSize)) {
+                pw.println("Override size: " + baseSize.x + "x" + baseSize.y);
+            }
+        } catch (RemoteException e) {
+            // Can't call getInitialDisplaySize() on IWindowManager or
+            // Can't call getBaseDisplaySize() on IWindowManager
+            pw.println("Remote exception: " + e);
+        }
+    }
+
     private int runDisplaySize(PrintWriter pw) throws RemoteException {
         String size = getNextArg();
         int w, h;
+        final int displayId = getDisplayId(size);
         if (size == null) {
-            Point initialSize = new Point();
-            Point baseSize = new Point();
-            try {
-                mInterface.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);
-                mInterface.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);
-                pw.println("Physical size: " + initialSize.x + "x" + initialSize.y);
-                if (!initialSize.equals(baseSize)) {
-                    pw.println("Override size: " + baseSize.x + "x" + baseSize.y);
-                }
-            } catch (RemoteException e) {
-            }
+            printInitialDisplaySize(pw, displayId);
+            return 0;
+        } else if ("-d".equals(size)) {
+            printInitialDisplaySize(pw, displayId);
             return 0;
         } else if ("reset".equals(size)) {
             w = h = -1;
@@ -114,8 +136,8 @@
             String wstr = size.substring(0, div);
             String hstr = size.substring(div+1);
             try {
-                w = parseDimension(wstr);
-                h = parseDimension(hstr);
+                w = parseDimension(wstr, displayId);
+                h = parseDimension(hstr, displayId);
             } catch (NumberFormatException e) {
                 getErrPrintWriter().println("Error: bad number " + e);
                 return -1;
@@ -123,27 +145,38 @@
         }
 
         if (w >= 0 && h >= 0) {
-            // TODO(multidisplay): For now Configuration only applies to main screen.
-            mInterface.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);
+            mInterface.setForcedDisplaySize(displayId, w, h);
         } else {
-            mInterface.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
+            mInterface.clearForcedDisplaySize(displayId);
         }
         return 0;
     }
 
+    private void printInitialDisplayDensity(PrintWriter pw , int displayId) {
+        try {
+            final int initialDensity = mInterface.getInitialDisplayDensity(displayId);
+            final int baseDensity = mInterface.getBaseDisplayDensity(displayId);
+            pw.println("Physical density: " + initialDensity);
+            if (initialDensity != baseDensity) {
+                pw.println("Override density: " + baseDensity);
+            }
+        } catch (RemoteException e) {
+            // Can't call getInitialDisplayDensity() on IWindowManager or
+            // Can't call getBaseDisplayDensity() on IWindowManager
+            pw.println("Remote exception: " + e);
+        }
+    }
+
     private int runDisplayDensity(PrintWriter pw) throws RemoteException {
         String densityStr = getNextArg();
         int density;
+        final int displayId = getDisplayId(densityStr);
+
         if (densityStr == null) {
-            try {
-                int initialDensity = mInterface.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);
-                int baseDensity = mInterface.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
-                pw.println("Physical density: " + initialDensity);
-                if (initialDensity != baseDensity) {
-                    pw.println("Override density: " + baseDensity);
-                }
-            } catch (RemoteException e) {
-            }
+            printInitialDisplayDensity(pw, displayId);
+            return 0;
+        } else if ("-d".equals(densityStr)) {
+            printInitialDisplayDensity(pw, displayId);
             return 0;
         } else if ("reset".equals(densityStr)) {
             density = -1;
@@ -161,11 +194,10 @@
         }
 
         if (density > 0) {
-            // TODO(multidisplay): For now Configuration only applies to main screen.
-            mInterface.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density,
+            mInterface.setForcedDisplayDensityForUser(displayId, density,
                     UserHandle.USER_CURRENT);
         } else {
-            mInterface.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY,
+            mInterface.clearForcedDisplayDensityForUser(displayId,
                     UserHandle.USER_CURRENT);
         }
         return 0;
@@ -174,6 +206,7 @@
     private int runDisplayOverscan(PrintWriter pw) throws RemoteException {
         String overscanStr = getNextArgRequired();
         Rect rect = new Rect();
+        final int displayId = getDisplayId(overscanStr);
         if ("reset".equals(overscanStr)) {
             rect.set(0, 0, 0, 0);
         } else {
@@ -190,17 +223,16 @@
             rect.bottom = Integer.parseInt(matcher.group(4));
         }
 
-        mInterface.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right,
-                rect.bottom);
+        mInterface.setOverscan(displayId, rect.left, rect.top, rect.right, rect.bottom);
         return 0;
     }
 
     private int runDisplayScaling(PrintWriter pw) throws RemoteException {
         String scalingStr = getNextArgRequired();
         if ("auto".equals(scalingStr)) {
-            mInterface.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 0);
+            mInterface.setForcedDisplayScalingMode(getDisplayId(scalingStr), 0);
         } else if ("off".equals(scalingStr)) {
-            mInterface.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
+            mInterface.setForcedDisplayScalingMode(getDisplayId(scalingStr), 1);
         } else {
             getErrPrintWriter().println("Error: scaling must be 'auto' or 'off'");
             return -1;
@@ -213,14 +245,14 @@
         return 0;
     }
 
-    private int parseDimension(String s) throws NumberFormatException {
+    private int parseDimension(String s, int displayId) throws NumberFormatException {
         if (s.endsWith("px")) {
             return Integer.parseInt(s.substring(0, s.length() - 2));
         }
         if (s.endsWith("dp")) {
             int density;
             try {
-                density = mInterface.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
+                density = mInterface.getBaseDisplayDensity(displayId);
             } catch (RemoteException e) {
                 density = DisplayMetrics.DENSITY_DEFAULT;
             }
@@ -236,14 +268,14 @@
         pw.println("Window manager (window) commands:");
         pw.println("  help");
         pw.println("      Print this help text.");
-        pw.println("  size [reset|WxH|WdpxHdp]");
+        pw.println("  size [reset|WxH|WdpxHdp] [-d DISPLAY_ID]");
         pw.println("    Return or override display size.");
         pw.println("    width and height in pixels unless suffixed with 'dp'.");
-        pw.println("  density [reset|DENSITY]");
+        pw.println("  density [reset|DENSITY] [-d DISPLAY_ID]");
         pw.println("    Return or override display density.");
-        pw.println("  overscan [reset|LEFT,TOP,RIGHT,BOTTOM]");
+        pw.println("  overscan [reset|LEFT,TOP,RIGHT,BOTTOM] [-d DISPLAY ID]");
         pw.println("    Set overscan area for display.");
-        pw.println("  scaling [off|auto]");
+        pw.println("  scaling [off|auto] [-d DISPLAY_ID]");
         pw.println("    Set display scaling mode.");
         pw.println("  dismiss-keyguard");
         pw.println("    Dismiss the keyguard, prompting user for auth if necessary.");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5272b66..8276952 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -304,6 +304,8 @@
      */
     private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration();
 
+    private final Configuration mTempConfiguration = new Configuration();
+
     /**
      * The last content insets returned to the client in relayout. We use
      * these in the bounds animation to ensure we only observe inset changes
@@ -359,8 +361,6 @@
      */
     private final Rect mInsetFrame = new Rect();
 
-    boolean mContentChanged;
-
     // If a window showing a wallpaper: the requested offset for the
     // wallpaper; if a wallpaper window: the currently applied offset.
     float mWallpaperX = -1;
@@ -593,14 +593,14 @@
 
         if (mForceSeamlesslyRotate || requested) {
             mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo());
-            mPendingSeamlessRotate.unrotate(transaction, this.mToken);
+            mPendingSeamlessRotate.unrotate(transaction, this);
             mService.markForSeamlessRotation(this, true);
         }
     }
 
     void finishSeamlessRotation() {
         if (mPendingSeamlessRotate != null) {
-            mPendingSeamlessRotate.finish(this.mToken, this);
+            mPendingSeamlessRotate.finish(this);
             mFinishSeamlessRotateFrameNumber = getFrameNumber();
             mPendingSeamlessRotate = null;
             mService.markForSeamlessRotation(this, false);
@@ -787,7 +787,7 @@
     }
 
     @Override
-    public void computeFrameLw(WindowFrames windowFrames) {
+    public void computeFrameLw() {
         if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
             // This window is being replaced and either already got information that it's being
             // removed or we are still waiting for some information. Because of this we don't
@@ -796,8 +796,6 @@
             return;
         }
         mHaveFrame = true;
-        mWindowFrames.setParentFrameWasClippedByDisplayCutout(
-                windowFrames.parentFrameWasClippedByDisplayCutout());
 
         final Task task = getTask();
         final boolean inFullscreenContainer = inFullscreenContainer();
@@ -827,10 +825,9 @@
         final int layoutYDiff;
         if (inFullscreenContainer || layoutInParentFrame()) {
             // We use the parent frame as the containing frame for fullscreen and child windows
-            mWindowFrames.mContainingFrame.set(windowFrames.mParentFrame);
-            mWindowFrames.mDisplayFrame.set(windowFrames.mDisplayFrame);
-            layoutDisplayFrame = windowFrames.mDisplayFrame;
-            layoutContainingFrame = windowFrames.mParentFrame;
+            mWindowFrames.mContainingFrame.set(mWindowFrames.mParentFrame);
+            layoutDisplayFrame = mWindowFrames.mDisplayFrame;
+            layoutContainingFrame = mWindowFrames.mParentFrame;
             layoutXDiff = 0;
             layoutYDiff = 0;
         } else {
@@ -849,17 +846,17 @@
             // IME is up and obscuring this window. Adjust the window position so it is visible.
             if (imeWin != null && imeWin.isVisibleNow() && isInputMethodTarget()) {
                 if (inFreeformWindowingMode() && mWindowFrames.mContainingFrame.bottom
-                        > windowFrames.mContentFrame.bottom) {
+                        > mWindowFrames.mContentFrame.bottom) {
                     // In freeform we want to move the top up directly.
                     // TODO: Investigate why this is contentFrame not parentFrame.
                     mWindowFrames.mContainingFrame.top -= mWindowFrames.mContainingFrame.bottom
-                            - windowFrames.mContentFrame.bottom;
+                            - mWindowFrames.mContentFrame.bottom;
                 } else if (!inPinnedWindowingMode() && mWindowFrames.mContainingFrame.bottom
-                        > windowFrames.mParentFrame.bottom) {
+                        > mWindowFrames.mParentFrame.bottom) {
                     // But in docked we want to behave like fullscreen and behave as if the task
                     // were given smaller bounds for the purposes of layout. Skip adjustments for
                     // the pinned stack, they are handled separately in the PinnedStackController.
-                    mWindowFrames.mContainingFrame.bottom = windowFrames.mParentFrame.bottom;
+                    mWindowFrames.mContainingFrame.bottom = mWindowFrames.mParentFrame.bottom;
                 }
             }
 
@@ -868,7 +865,7 @@
                 // if it wasn't set already. No need to intersect it with the (visible)
                 // "content frame" since it is allowed to be outside the visible desktop.
                 if (mWindowFrames.mContainingFrame.isEmpty()) {
-                    mWindowFrames.mContainingFrame.set(windowFrames.mContentFrame);
+                    mWindowFrames.mContainingFrame.set(mWindowFrames.mContentFrame);
                 }
             }
 
@@ -878,10 +875,11 @@
                 // PIP edge case: When going from pinned to fullscreen, we apply a
                 // tempInsetFrame for the full task - but we're still at the start of the animation.
                 // To prevent a jump if there's a letterbox, restrict to the parent frame.
-                mInsetFrame.intersectUnchecked(windowFrames.mParentFrame);
-                mWindowFrames.mContainingFrame.intersectUnchecked(windowFrames.mParentFrame);
+                mInsetFrame.intersectUnchecked(mWindowFrames.mParentFrame);
+                mWindowFrames.mContainingFrame.intersectUnchecked(mWindowFrames.mParentFrame);
             }
 
+            layoutDisplayFrame = new Rect(mWindowFrames.mDisplayFrame);
             mWindowFrames.mDisplayFrame.set(mWindowFrames.mContainingFrame);
             layoutXDiff =
                     !mInsetFrame.isEmpty() ? mInsetFrame.left - mWindowFrames.mContainingFrame.left
@@ -892,41 +890,24 @@
             layoutContainingFrame =
                     !mInsetFrame.isEmpty() ? mInsetFrame : mWindowFrames.mContainingFrame;
             mTmpRect.set(0, 0, dc.getDisplayInfo().logicalWidth, dc.getDisplayInfo().logicalHeight);
-            subtractInsets(mWindowFrames.mDisplayFrame, layoutContainingFrame,
-                    windowFrames.mDisplayFrame, mTmpRect);
+            subtractInsets(mWindowFrames.mDisplayFrame, layoutContainingFrame, layoutDisplayFrame,
+                    mTmpRect);
             if (!layoutInParentFrame()) {
                 subtractInsets(mWindowFrames.mContainingFrame, layoutContainingFrame,
-                        windowFrames.mParentFrame, mTmpRect);
-                subtractInsets(mInsetFrame, layoutContainingFrame, windowFrames.mParentFrame,
+                        mWindowFrames.mParentFrame, mTmpRect);
+                subtractInsets(mInsetFrame, layoutContainingFrame, mWindowFrames.mParentFrame,
                         mTmpRect);
             }
-            layoutDisplayFrame = windowFrames.mDisplayFrame;
             layoutDisplayFrame.intersect(layoutContainingFrame);
         }
 
         final int pw = mWindowFrames.mContainingFrame.width();
         final int ph = mWindowFrames.mContainingFrame.height();
 
-        if (!mWindowFrames.mParentFrame.equals(windowFrames.mParentFrame)) {
-            //Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame
-            //        + " to " + parentFrame);
-            mWindowFrames.mParentFrame.set(windowFrames.mParentFrame);
-            mContentChanged = true;
-        }
         if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
             mLastRequestedWidth = mRequestedWidth;
             mLastRequestedHeight = mRequestedHeight;
-            mContentChanged = true;
-        }
-
-        mWindowFrames.mOverscanFrame.set(windowFrames.mOverscanFrame);
-        mWindowFrames.mContentFrame.set(windowFrames.mContentFrame);
-        mWindowFrames.mVisibleFrame.set(windowFrames.mVisibleFrame);
-        mWindowFrames.mDecorFrame.set(windowFrames.mDecorFrame);
-        mWindowFrames.mStableFrame.set(windowFrames.mStableFrame);
-        final boolean hasOutsets = !windowFrames.mOutsetFrame.isEmpty();
-        if (hasOutsets) {
-            mWindowFrames.mOutsetFrame.set(windowFrames.mOutsetFrame);
+            mWindowFrames.setContentChanged(true);
         }
 
         final int fw = mWindowFrames.mFrame.width();
@@ -935,7 +916,7 @@
         applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame);
 
         // Calculate the outsets before the content frame gets shrinked to the window frame.
-        mWindowFrames.calculateOutsets(hasOutsets);
+        mWindowFrames.calculateOutsets();
 
         // Make sure the content and visible frames are inside of the
         // final window frame.
@@ -997,7 +978,7 @@
         }
 
         if (mAttrs.type == TYPE_DOCK_DIVIDER) {
-            final WmDisplayCutout c = windowFrames.mDisplayCutout.calculateRelativeTo(
+            final WmDisplayCutout c = mWindowFrames.mDisplayCutout.calculateRelativeTo(
                     mWindowFrames.mDisplayFrame);
             mWindowFrames.calculateDockedDividerInsets(c.getDisplayCutout().getSafeInsets());
         } else {
@@ -1006,7 +987,7 @@
         }
 
         mWindowFrames.setDisplayCutout(
-                windowFrames.mDisplayCutout.calculateRelativeTo(mWindowFrames.mFrame));
+                mWindowFrames.mDisplayCutout.calculateRelativeTo(mWindowFrames.mFrame));
 
         // Offset the actual frame by the amount layout frame is off.
         mWindowFrames.offsetFrames(-layoutXDiff, -layoutYDiff);
@@ -1280,6 +1261,7 @@
 
     @Override
     void onDisplayChanged(DisplayContent dc) {
+        updateSurfaceSize(dc);
         super.onDisplayChanged(dc);
         // Window was not laid out for this display yet, so make sure mLayoutSeq does not match.
         if (dc != null) {
@@ -1382,7 +1364,7 @@
     @Override
     boolean hasContentToDisplay() {
         if (!mAppFreezing && isDrawnLw() && (mViewVisibility == View.VISIBLE
-                || (mWinAnimator.isAnimationSet() && !mService.mAppTransition.isTransitionSet()))) {
+                || (isAnimating() && !mService.mAppTransition.isTransitionSet()))) {
             return true;
         }
 
@@ -1461,9 +1443,9 @@
         final AppWindowToken atoken = mAppToken;
         if (atoken != null) {
             return ((!isParentWindowHidden() && !atoken.hiddenRequested)
-                    || mWinAnimator.isAnimationSet());
+                    || isAnimating());
         }
-        return !isParentWindowHidden() || mWinAnimator.isAnimationSet();
+        return !isParentWindowHidden() || isAnimating();
     }
 
     /**
@@ -1494,9 +1476,10 @@
         if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
             return false;
         }
+        final boolean parentAndClientVisible = !isParentWindowHidden()
+                && mViewVisibility == View.VISIBLE && !mToken.isHidden();
         return mHasSurface && mPolicyVisibility && !mDestroying
-                && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.isHidden())
-                        || mWinAnimator.isAnimationSet());
+                && (parentAndClientVisible || isAnimating());
     }
 
     // TODO: Another visibility method that was added late in the release to minimize risk.
@@ -1526,7 +1509,7 @@
         final AppWindowToken atoken = mAppToken;
         return isDrawnLw() && mPolicyVisibility
                 && ((!isParentWindowHidden() && (atoken == null || !atoken.hiddenRequested))
-                        || mWinAnimator.isAnimationSet());
+                        || isAnimating());
     }
 
     /**
@@ -1580,7 +1563,7 @@
         // to determine if it's occluding apps.
         return ((!mIsWallpaper && mAttrs.format == PixelFormat.OPAQUE)
                 || (mIsWallpaper && mWallpaperVisible))
-                && isDrawnLw() && !mWinAnimator.isAnimationSet();
+                && isDrawnLw() && !isAnimating();
     }
 
     @Override
@@ -1733,7 +1716,7 @@
      * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
      */
     private boolean hasMoved() {
-        return mHasSurface && (mContentChanged || mMovedByResize)
+        return mHasSurface && (mWindowFrames.hasContentChanged() || mMovedByResize)
                 && !mAnimatingExit
                 && (mWindowFrames.mFrame.top != mWindowFrames.mLastFrame.top
                     || mWindowFrames.mFrame.left != mWindowFrames.mLastFrame.left)
@@ -1850,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="
@@ -1867,7 +1850,7 @@
                     + " mRemoveOnExit=" + mRemoveOnExit
                     + " mHasSurface=" + mHasSurface
                     + " surfaceShowing=" + mWinAnimator.getShown()
-                    + " isAnimationSet=" + mWinAnimator.isAnimationSet()
+                    + " animating=" + isAnimating()
                     + " app-animation="
                     + (mAppToken != null ? mAppToken.isSelfAnimating() : "false")
                     + " mWillReplaceWindow=" + mWillReplaceWindow
@@ -1934,7 +1917,7 @@
                         mService.mAccessibilityController.onWindowTransitionLocked(this, transit);
                     }
                 }
-                final boolean isAnimating = mWinAnimator.isAnimationSet()
+                final boolean isAnimating = isAnimating()
                         && (mAppToken == null || !mAppToken.isWaitingForTransitionStart());
                 final boolean lastWindowIsStartingWindow = startingWindow && mAppToken != null
                         && mAppToken.isLastWindow(this);
@@ -1962,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*/);
@@ -2197,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;
@@ -2270,8 +2253,17 @@
         }
     }
 
+    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;
+        mTempConfiguration.setTo(mService.mProcessConfigurations.get(
+                pid, mService.mRoot.getConfiguration()));
+        return mTempConfiguration;
+    }
+
     void getMergedConfiguration(MergedConfiguration outConfiguration) {
-        final Configuration globalConfig = mService.mRoot.getConfiguration();
+        final Configuration globalConfig = getProcessGlobalConfiguration();
         final Configuration overrideConfig = getMergedOverrideConfiguration();
         outConfiguration.setConfiguration(globalConfig, overrideConfig);
     }
@@ -2443,10 +2435,10 @@
         if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
         if (doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
-                    + mPolicyVisibility + " isAnimationSet=" + mWinAnimator.isAnimationSet());
+                    + mPolicyVisibility + " animating=" + isAnimating());
             if (!mToken.okToAnimate()) {
                 doAnimation = false;
-            } else if (mPolicyVisibility && !mWinAnimator.isAnimationSet()) {
+            } else if (mPolicyVisibility && !isAnimating()) {
                 // Check for the case where we are currently visible and
                 // not animating; we do not want to do animation at such a
                 // point to become visible when we already are.
@@ -2485,11 +2477,12 @@
         }
         if (doAnimation) {
             mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
-            if (!mWinAnimator.isAnimationSet()) {
+            if (!isAnimating()) {
                 doAnimation = false;
             }
         }
         mPolicyVisibilityAfterAnim = false;
+        final boolean isFocused = isFocused();
         if (!doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
             mPolicyVisibility = false;
@@ -2497,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;
@@ -2506,7 +2499,7 @@
         if (requestAnim) {
             mService.scheduleAnimationLocked();
         }
-        if (mService.mCurrentFocus == this) {
+        if (isFocused) {
             mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateImWindows */);
         }
         return true;
@@ -2874,7 +2867,11 @@
             return mAppToken.mFrozenMergedConfig.peek();
         }
 
-        return super.getConfiguration();
+        // We use the process config this window is associated with as the based global config since
+        // the process can override it config, but isn't part of the window hierarchy.
+        final Configuration config = getProcessGlobalConfiguration();
+        config.updateFrom(getMergedOverrideConfiguration());
+        return config;
     }
 
     void reportResized() {
@@ -2998,10 +2995,8 @@
         }
     }
 
-    public boolean isFocused() {
-        synchronized(mService.mWindowMap) {
-            return mService.mCurrentFocus == this;
-        }
+    boolean isFocused() {
+        return getDisplayContent().mCurrentFocus == this;
     }
 
     @Override
@@ -3221,10 +3216,8 @@
                     + " mWallpaperVisible=" + mWallpaperVisible);
         }
         if (dumpAll) {
-            pw.println(prefix + "mBaseLayer=" + mBaseLayer
-                    + " mSubLayer=" + mSubLayer
-                    + " mAnimLayer=" + mLayer + "=" + mWinAnimator.mAnimLayer
-                    + " mLastLayer=" + mWinAnimator.mLastLayer);
+            pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
+                    pw.print(" mSubLayer="); pw.print(mSubLayer);
         }
         if (dumpAll) {
             pw.println(prefix + "mToken=" + mToken);
@@ -3702,7 +3695,7 @@
                     + " tok.hiddenRequested="
                     + (mAppToken != null && mAppToken.hiddenRequested)
                     + " tok.hidden=" + (mAppToken != null && mAppToken.isHidden())
-                    + " animationSet=" + mWinAnimator.isAnimationSet()
+                    + " animating=" + isAnimating()
                     + " tok animating="
                     + (mAppToken != null && mAppToken.isSelfAnimating())
                     + " Callers=" + Debug.getCallers(4));
@@ -3754,18 +3747,6 @@
         return windowInfo;
     }
 
-    int getHighestAnimLayer() {
-        int highest = mWinAnimator.mAnimLayer;
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            final WindowState c = mChildren.get(i);
-            final int childLayer = c.getHighestAnimLayer();
-            if (childLayer > highest) {
-                highest = childLayer;
-            }
-        }
-        return highest;
-    }
-
     @Override
     boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         if (mChildren.isEmpty()) {
@@ -4115,25 +4096,25 @@
         }
         if (DEBUG_VISIBILITY) {
             Slog.v(TAG, "Win " + this + ": isDrawn=" + isDrawnLw()
-                    + ", isAnimationSet=" + mWinAnimator.isAnimationSet());
+                    + ", animating=" + isAnimating());
             if (!isDrawnLw()) {
                 Slog.v(TAG, "Not displayed: s=" + mWinAnimator.mSurfaceController
                         + " pv=" + mPolicyVisibility
                         + " mDrawState=" + mWinAnimator.mDrawState
                         + " ph=" + isParentWindowHidden()
                         + " th=" + (mAppToken != null ? mAppToken.hiddenRequested : false)
-                        + " a=" + mWinAnimator.isAnimationSet());
+                        + " a=" + isAnimating());
             }
         }
 
         results.numInteresting++;
         if (isDrawnLw()) {
             results.numDrawn++;
-            if (!mWinAnimator.isAnimationSet()) {
+            if (!isAnimating()) {
                 results.numVisible++;
             }
             results.nowGone = false;
-        } else if (mWinAnimator.isAnimationSet()) {
+        } else if (isAnimating()) {
             results.nowGone = false;
         }
     }
@@ -4453,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;
         }
     }
 
@@ -4540,7 +4526,8 @@
         updateSurfacePosition(getPendingTransaction());
     }
 
-    private void updateSurfacePosition(Transaction t) {
+    @VisibleForTesting
+    void updateSurfacePosition(Transaction t) {
         if (mSurfaceControl == null) {
             return;
         }
@@ -4680,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. */
@@ -4762,6 +4746,15 @@
         return mWindowFrames.mVisibleInsets;
     }
 
+    @Override
+    public WindowFrames getWindowFrames() {
+        return mWindowFrames;
+    }
+
+    void resetContentChanged() {
+        mWindowFrames.setContentChanged(false);
+    }
+
     private final class MoveAnimationSpec implements AnimationSpec {
 
         private final long mDuration;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 979149a..2beb788 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -107,8 +107,6 @@
     private final WallpaperController mWallpaperControllerLocked;
 
     boolean mAnimationIsEntrance;
-    int mAnimLayer;
-    int mLastLayer;
 
     /**
      * Set when we have changed the size of the surface, to know that
@@ -135,7 +133,6 @@
     float mLastAlpha = 0;
 
     Rect mTmpClipRect = new Rect();
-    Rect mTmpFinalClipRect = new Rect();
     Rect mLastClipRect = new Rect();
     Rect mLastFinalClipRect = new Rect();
     Rect mTmpStackBounds = new Rect();
@@ -162,8 +159,6 @@
      * window is first added or shown, cleared when the callback has been made. */
     boolean mEnteringAnimation;
 
-    private boolean mAnimationStartDelayed;
-
     private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
 
     /** The pixel format of the underlying SurfaceControl */
@@ -253,13 +248,6 @@
         mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
     }
 
-    /**
-     * Is the window or its container currently set to animate or currently animating?
-     */
-    boolean isAnimationSet() {
-        return mWin.isAnimating();
-    }
-
     void cancelExitAnimationForNextAnimationLocked() {
         if (DEBUG_ANIM) Slog.d(TAG,
                 "cancelExitAnimationForNextAnimationLocked: " + mWin);
@@ -275,10 +263,6 @@
                         + ", reportedVisible="
                         + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
 
-        if (mAnimator.mWindowDetachedWallpaper == mWin) {
-            mAnimator.mWindowDetachedWallpaper = null;
-        }
-
         mWin.checkPolicyVisibilityChange();
         final DisplayContent displayContent = mWin.getDisplayContent();
         if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
@@ -288,7 +272,6 @@
                 displayContent.setLayoutNeeded();
             }
         }
-
         mWin.onExitAnimationDone();
         final int displayId = mWin.getDisplayId();
         int pendingLayoutChanges = FINISH_LAYOUT_REDO_ANIM;
@@ -539,14 +522,13 @@
         }
 
         if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController
-                + ", set left=" + w.getFrameLw().left + " top=" + w.getFrameLw().top
-                + ", animLayer=" + mAnimLayer);
+                + ", set left=" + w.getFrameLw().left + " top=" + w.getFrameLw().top);
 
         if (SHOW_LIGHT_TRANSACTIONS) {
             Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
             WindowManagerService.logSurface(w, "CREATE pos=("
                     + w.getFrameLw().left + "," + w.getFrameLw().top + ") ("
-                    + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
+                    + width + "x" + height + ")" + " HIDE", false);
         }
 
         mLastHidden = true;
@@ -1133,8 +1115,7 @@
                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation change skips hidden " + w);
             }
-        } else if (mLastLayer != mAnimLayer
-                || mLastAlpha != mShownAlpha
+        } else if (mLastAlpha != mShownAlpha
                 || mLastDsDx != mDsDx
                 || mLastDtDx != mDtDx
                 || mLastDsDy != mDsDy
@@ -1144,7 +1125,6 @@
                 || mLastHidden) {
             displayed = true;
             mLastAlpha = mShownAlpha;
-            mLastLayer = mAnimLayer;
             mLastDsDx = mDsDx;
             mLastDtDx = mDtDx;
             mLastDsDy = mDsDy;
@@ -1153,7 +1133,7 @@
             w.mLastVScale = w.mVScale;
             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
                     "controller=" + mSurfaceController +
-                    "alpha=" + mShownAlpha + " layer=" + mAnimLayer
+                    "alpha=" + mShownAlpha
                     + " matrix=[" + mDsDx + "*" + w.mHScale
                     + "," + mDtDx + "*" + w.mVScale
                     + "][" + mDtDy + "*" + w.mHScale
@@ -1197,7 +1177,7 @@
                 w.mToken.hasVisible = true;
             }
         } else {
-            if (DEBUG_ANIM && isAnimationSet()) {
+            if (DEBUG_ANIM && mWin.isAnimating()) {
                 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
             }
             displayed = true;
@@ -1407,7 +1387,7 @@
         }
 
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
-        return isAnimationSet();
+        return mWin.isAnimating();
     }
 
     void writeToProto(ProtoOutputStream proto, long fieldId) {
@@ -1460,9 +1440,6 @@
                     pw.print(" mDtDy="); pw.print(mDtDy);
                     pw.print(" mDsDy="); pw.println(mDsDy);
         }
-        if (mAnimationStartDelayed) {
-            pw.print(prefix); pw.print("mAnimationStartDelayed="); pw.print(mAnimationStartDelayed);
-        }
     }
 
     @Override
@@ -1520,10 +1497,6 @@
         mChildrenDetached = true;
     }
 
-    int getLayer() {
-        return mLastLayer;
-    }
-
     void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {
         mOffsetPositionForStackResize = offsetPositionForStackResize;
     }
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index d6f9ac3..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;
@@ -92,19 +91,12 @@
 
     static final int SET_UPDATE_ROTATION                = 1 << 0;
     static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
-    static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
-    static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 3;
-    static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 4;
+    static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 2;
+    static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 3;
 
     private boolean mTraversalScheduled;
     private int mDeferDepth = 0;
 
-    private static final class LayerAndToken {
-        public int layer;
-        public AppWindowToken token;
-    }
-    private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
-
     private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
 
     private final Runnable mPerformSurfacePlacement;
@@ -259,7 +251,7 @@
         mService.mSkipAppTransitionAnimation = false;
         mService.mNoAnimationNotifyOnTransitionFinished.clear();
 
-        mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
+        mService.mAppTransition.removeAppTransitionTimeoutCallbacks();
 
         final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
 
@@ -299,10 +291,16 @@
         // done behind a dream window.
         final ArraySet<Integer> activityTypes = collectActivityTypes(mService.mOpeningApps,
                 mService.mClosingApps);
-        final AppWindowToken animLpToken = mService.mPolicy.allowAppAnimationsLw()
+        final boolean allowAnimations = mService.mPolicy.allowAppAnimationsLw();
+        final AppWindowToken animLpToken = allowAnimations
                 ? findAnimLayoutParamsToken(transit, activityTypes)
                 : null;
-
+        final AppWindowToken topOpeningApp = allowAnimations
+                ? getTopApp(mService.mOpeningApps, false /* ignoreHidden */)
+                : null;
+        final AppWindowToken topClosingApp = allowAnimations
+                ? getTopApp(mService.mClosingApps, false /* ignoreHidden */)
+                : null;
         final LayoutParams animLp = getAnimLp(animLpToken);
         overrideWithRemoteAnimationIfSet(animLpToken, transit, activityTypes);
 
@@ -314,17 +312,14 @@
         try {
             processApplicationsAnimatingInPlace(transit);
 
-            mTmpLayerAndToken.token = null;
-            handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
-            final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
-            final AppWindowToken topOpeningApp = handleOpeningApps(transit, animLp,
-                    voiceInteraction);
+            handleClosingApps(transit, animLp, voiceInteraction);
+            handleOpeningApps(transit, animLp, voiceInteraction);
 
             mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
 
             final int flags = mService.mAppTransition.getTransitFlags();
-            layoutRedo = mService.mAppTransition.goodToGo(transit, topOpeningApp,
-                    topClosingApp, mService.mOpeningApps, mService.mClosingApps);
+            layoutRedo = mService.mAppTransition.goodToGo(transit, topOpeningApp, topClosingApp,
+                    mService.mOpeningApps, mService.mClosingApps);
             handleNonAppWindowsInTransition(transit, flags);
             mService.mAppTransition.postAnimationCallback();
             mService.mAppTransition.clear();
@@ -451,10 +446,7 @@
         return false;
     }
 
-    private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
-            boolean voiceInteraction) {
-        AppWindowToken topOpeningApp = null;
-        int topOpeningLayer = Integer.MIN_VALUE;
+    private void handleOpeningApps(int transit, LayoutParams animLp, boolean voiceInteraction) {
         final int appsCount = mService.mOpeningApps.size();
         for (int i = 0; i < appsCount; i++) {
             AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
@@ -479,24 +471,15 @@
                         "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
             }
 
-            if (animLp != null) {
-                final int layer = wtoken.getHighestAnimLayer();
-                if (topOpeningApp == null || layer > topOpeningLayer) {
-                    topOpeningApp = wtoken;
-                    topOpeningLayer = layer;
-                }
-            }
             if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
                 wtoken.attachThumbnailAnimation();
             } else if (mService.mAppTransition.isNextAppTransitionOpenCrossProfileApps()) {
                 wtoken.attachCrossProfileAppsThumbnailAnimation();
             }
         }
-        return topOpeningApp;
     }
 
-    private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
-            LayerAndToken layerAndToken) {
+    private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction) {
         final int appsCount;
         appsCount = mService.mClosingApps.size();
         for (int i = 0; i < appsCount; i++) {
@@ -519,13 +502,6 @@
                 wtoken.getController().removeStartingWindow();
             }
 
-            if (animLp != null) {
-                int layer = wtoken.getHighestAnimLayer();
-                if (layerAndToken.token == null || layer > layerAndToken.layer) {
-                    layerAndToken.token = wtoken;
-                    layerAndToken.layer = layer;
-                }
-            }
             if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
                 wtoken.attachThumbnailAnimation();
             }
@@ -786,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 e411c0a..0cf79b6 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -162,7 +163,7 @@
 
         for (int i = 0; i < count; i++) {
             final WindowState win = mChildren.get(i);
-            if (win.mWinAnimator.isAnimationSet()) {
+            if (win.isAnimating()) {
                 delayed = true;
             }
             changed |= win.onSetAppExiting();
@@ -234,18 +235,6 @@
         return false;
     }
 
-    int getHighestAnimLayer() {
-        int highest = -1;
-        for (int j = 0; j < mChildren.size(); j++) {
-            final WindowState w = mChildren.get(j);
-            final int wLayer = w.getHighestAnimLayer();
-            if (wLayer > highest) {
-                highest = wLayer;
-            }
-        }
-        return highest;
-    }
-
     AppWindowToken asAppWindowToken() {
         // TODO: Not sure if this is the best way to handle this vs. using instanceof and casting.
         // I am not an app window token!
@@ -266,6 +255,7 @@
         super.removeImmediately();
     }
 
+    @Override
     void onDisplayChanged(DisplayContent dc) {
         dc.reParentWindowToken(this);
         mDisplayContent = dc;
@@ -275,6 +265,7 @@
         // to another display before the window behind
         // it is ready.
 
+        updateSurfaceSize(dc);
         super.onDisplayChanged(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 becde73..045f4eb 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,14 +30,13 @@
         "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",
         "com_android_server_net_NetworkStatsService.cpp",
         "com_android_server_power_PowerManagerService.cpp",
+        "com_android_server_security_VerityUtils.cpp",
         "com_android_server_SerialService.cpp",
         "com_android_server_storage_AppFuseBridge.cpp",
         "com_android_server_SystemServer.cpp",
@@ -89,7 +89,6 @@
         "libsensorservicehidl",
         "libgui",
         "libusbhost",
-        "libsuspend",
         "libtinyalsa",
         "libEGL",
         "libGLESv2",
@@ -121,6 +120,7 @@
         "android.hardware.vr@1.0",
         "android.frameworks.schedulerservice@1.0",
         "android.frameworks.sensorservice@1.0",
+        "android.system.suspend@1.0",
     ],
 
     static_libs: [
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_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 02ad6c7..0ff60e4 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -30,6 +30,8 @@
 
 #include <android/hardware/power/1.0/IPower.h>
 #include <android/hardware/power/1.1/IPower.h>
+#include <android/system/suspend/1.0/ISystemSuspend.h>
+#include <android/system/suspend/1.0/ISystemSuspendCallback.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <jni.h>
 
@@ -39,7 +41,6 @@
 #include <log/log.h>
 #include <utils/misc.h>
 #include <utils/Log.h>
-#include <suspend/autosuspend.h>
 
 using android::hardware::Return;
 using android::hardware::Void;
@@ -49,6 +50,8 @@
 using android::hardware::power::V1_1::PowerStateSubsystem;
 using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
 using android::hardware::hidl_vec;
+using android::system::suspend::V1_0::ISystemSuspend;
+using android::system::suspend::V1_0::ISystemSuspendCallback;
 using IPowerV1_1 = android::hardware::power::V1_1::IPower;
 using IPowerV1_0 = android::hardware::power::V1_0::IPower;
 
@@ -63,6 +66,7 @@
 extern sp<IPowerV1_0> getPowerHalV1_0();
 extern sp<IPowerV1_1> getPowerHalV1_1();
 extern bool processPowerHalReturn(const Return<void> &ret, const char* functionName);
+extern sp<ISystemSuspend> getSuspendHal();
 
 // Java methods used in getLowPowerStats
 static jmethodID jgetAndUpdatePlatformState = NULL;
@@ -70,16 +74,19 @@
 static jmethodID jputVoter = NULL;
 static jmethodID jputState = NULL;
 
-static void wakeup_callback(bool success)
-{
-    ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
-    int ret = sem_post(&wakeup_sem);
-    if (ret < 0) {
-        char buf[80];
-        strerror_r(errno, buf, sizeof(buf));
-        ALOGE("Error posting wakeup sem: %s\n", buf);
+class WakeupCallback : public ISystemSuspendCallback {
+public:
+    Return<void> notifyWakeup(bool success) override {
+        ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
+        int ret = sem_post(&wakeup_sem);
+        if (ret < 0) {
+            char buf[80];
+            strerror_r(errno, buf, sizeof(buf));
+            ALOGE("Error posting wakeup sem: %s\n", buf);
+        }
+        return Void();
     }
-}
+};
 
 static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
 {
@@ -101,11 +108,14 @@
             return -1;
         }
         ALOGV("Registering callback...");
-        autosuspend_set_wakeup_callback(&wakeup_callback);
+        sp<ISystemSuspend> suspendHal = getSuspendHal();
+        suspendHal->registerCallback(new WakeupCallback());
     }
 
     // Wait for wakeup.
     ALOGV("Waiting for wakeup...");
+    // TODO(b/116747600): device can suspend and wakeup after sem_wait() finishes and before wakeup
+    // reason is recorded, i.e. BatteryStats might occasionally miss wakeup events.
     int ret = sem_wait(&wakeup_sem);
     if (ret < 0) {
         char buf[80];
diff --git a/services/core/jni/com_android_server_input_InputApplicationHandle.cpp b/services/core/jni/com_android_server_input_InputApplicationHandle.cpp
deleted file mode 100644
index 514b6e1..0000000
--- a/services/core/jni/com_android_server_input_InputApplicationHandle.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputApplicationHandle"
-
-#include <nativehelper/JNIHelp.h>
-#include "jni.h"
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/threads.h>
-
-#include "com_android_server_input_InputApplicationHandle.h"
-
-namespace android {
-
-static struct {
-    jfieldID ptr;
-    jfieldID name;
-    jfieldID dispatchingTimeoutNanos;
-} gInputApplicationHandleClassInfo;
-
-static Mutex gHandleMutex;
-
-
-// --- NativeInputApplicationHandle ---
-
-NativeInputApplicationHandle::NativeInputApplicationHandle(jweak objWeak) :
-        mObjWeak(objWeak) {
-}
-
-NativeInputApplicationHandle::~NativeInputApplicationHandle() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    env->DeleteWeakGlobalRef(mObjWeak);
-}
-
-jobject NativeInputApplicationHandle::getInputApplicationHandleObjLocalRef(JNIEnv* env) {
-    return env->NewLocalRef(mObjWeak);
-}
-
-bool NativeInputApplicationHandle::updateInfo() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jobject obj = env->NewLocalRef(mObjWeak);
-    if (!obj) {
-        releaseInfo();
-        return false;
-    }
-
-    if (!mInfo) {
-        mInfo = new InputApplicationInfo();
-    }
-
-    jstring nameObj = jstring(env->GetObjectField(obj,
-            gInputApplicationHandleClassInfo.name));
-    if (nameObj) {
-        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
-        mInfo->name = nameStr;
-        env->ReleaseStringUTFChars(nameObj, nameStr);
-        env->DeleteLocalRef(nameObj);
-    } else {
-        mInfo->name = "<null>";
-    }
-
-    mInfo->dispatchingTimeout = env->GetLongField(obj,
-            gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
-
-    env->DeleteLocalRef(obj);
-    return true;
-}
-
-
-// --- Global functions ---
-
-sp<InputApplicationHandle> android_server_InputApplicationHandle_getHandle(
-        JNIEnv* env, jobject inputApplicationHandleObj) {
-    if (!inputApplicationHandleObj) {
-        return NULL;
-    }
-
-    AutoMutex _l(gHandleMutex);
-
-    jlong ptr = env->GetLongField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr);
-    NativeInputApplicationHandle* handle;
-    if (ptr) {
-        handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr);
-    } else {
-        jweak objWeak = env->NewWeakGlobalRef(inputApplicationHandleObj);
-        handle = new NativeInputApplicationHandle(objWeak);
-        handle->incStrong((void*)android_server_InputApplicationHandle_getHandle);
-        env->SetLongField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr,
-                reinterpret_cast<jlong>(handle));
-    }
-    return handle;
-}
-
-
-// --- JNI ---
-
-static void android_server_InputApplicationHandle_nativeDispose(JNIEnv* env, jobject obj) {
-    AutoMutex _l(gHandleMutex);
-
-    jlong ptr = env->GetLongField(obj, gInputApplicationHandleClassInfo.ptr);
-    if (ptr) {
-        env->SetLongField(obj, gInputApplicationHandleClassInfo.ptr, 0);
-
-        NativeInputApplicationHandle* handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr);
-        handle->decStrong((void*)android_server_InputApplicationHandle_getHandle);
-    }
-}
-
-
-static const JNINativeMethod gInputApplicationHandleMethods[] = {
-    /* name, signature, funcPtr */
-    { "nativeDispose", "()V",
-            (void*) android_server_InputApplicationHandle_nativeDispose },
-};
-
-#define FIND_CLASS(var, className) \
-        var = env->FindClass(className); \
-        LOG_FATAL_IF(! (var), "Unable to find class " className);
-
-#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
-        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
-        LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
-
-int register_android_server_InputApplicationHandle(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputApplicationHandle",
-            gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
-    (void) res;  // Faked use when LOG_NDEBUG.
-    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
-
-    jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/input/InputApplicationHandle");
-
-    GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
-            "ptr", "J");
-
-    GET_FIELD_ID(gInputApplicationHandleClassInfo.name, clazz,
-            "name", "Ljava/lang/String;");
-
-    GET_FIELD_ID(gInputApplicationHandleClassInfo.dispatchingTimeoutNanos,
-            clazz,
-            "dispatchingTimeoutNanos", "J");
-
-    return 0;
-}
-
-} /* namespace android */
diff --git a/services/core/jni/com_android_server_input_InputApplicationHandle.h b/services/core/jni/com_android_server_input_InputApplicationHandle.h
deleted file mode 100644
index c9af711..0000000
--- a/services/core/jni/com_android_server_input_InputApplicationHandle.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
-#define _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
-
-#include <inputflinger/InputApplication.h>
-
-#include <nativehelper/JNIHelp.h>
-#include "jni.h"
-
-namespace android {
-
-class NativeInputApplicationHandle : public InputApplicationHandle {
-public:
-    explicit NativeInputApplicationHandle(jweak objWeak);
-    virtual ~NativeInputApplicationHandle();
-
-    jobject getInputApplicationHandleObjLocalRef(JNIEnv* env);
-
-    virtual bool updateInfo();
-
-private:
-    jweak mObjWeak;
-};
-
-
-extern sp<InputApplicationHandle> android_server_InputApplicationHandle_getHandle(
-        JNIEnv* env, jobject inputApplicationHandleObj);
-
-} // namespace android
-
-#endif // _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 42ade38..c66d03c 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);
     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,57 +415,32 @@
 
             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) {
@@ -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)) {
@@ -1356,7 +1321,7 @@
 
     sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
             inputChannelObj);
-    if (inputChannel == NULL) {
+    if (inputChannel == nullptr) {
         throwInputChannelNotInitialized(env);
         return;
     }
@@ -1385,12 +1350,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 +1419,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 +1462,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 +1515,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 +1628,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",
@@ -1681,8 +1651,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_input_InputWindowHandle.cpp b/services/core/jni/com_android_server_input_InputWindowHandle.cpp
deleted file mode 100644
index c13aa38..0000000
--- a/services/core/jni/com_android_server_input_InputWindowHandle.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputWindowHandle"
-
-#include <nativehelper/JNIHelp.h>
-#include "jni.h"
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/threads.h>
-
-#include <android_view_InputChannel.h>
-#include <android/graphics/Region.h>
-#include <ui/Region.h>
-
-#include "com_android_server_input_InputWindowHandle.h"
-#include "com_android_server_input_InputApplicationHandle.h"
-
-namespace android {
-
-static struct {
-    jfieldID ptr;
-    jfieldID inputApplicationHandle;
-    jfieldID inputChannel;
-    jfieldID name;
-    jfieldID layoutParamsFlags;
-    jfieldID layoutParamsType;
-    jfieldID dispatchingTimeoutNanos;
-    jfieldID frameLeft;
-    jfieldID frameTop;
-    jfieldID frameRight;
-    jfieldID frameBottom;
-    jfieldID scaleFactor;
-    jfieldID touchableRegion;
-    jfieldID visible;
-    jfieldID canReceiveKeys;
-    jfieldID hasFocus;
-    jfieldID hasWallpaper;
-    jfieldID paused;
-    jfieldID layer;
-    jfieldID ownerPid;
-    jfieldID ownerUid;
-    jfieldID inputFeatures;
-    jfieldID displayId;
-} gInputWindowHandleClassInfo;
-
-static Mutex gHandleMutex;
-
-
-// --- NativeInputWindowHandle ---
-
-NativeInputWindowHandle::NativeInputWindowHandle(
-        const sp<InputApplicationHandle>& inputApplicationHandle, jweak objWeak) :
-        InputWindowHandle(inputApplicationHandle),
-        mObjWeak(objWeak) {
-}
-
-NativeInputWindowHandle::~NativeInputWindowHandle() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    env->DeleteWeakGlobalRef(mObjWeak);
-}
-
-jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
-    return env->NewLocalRef(mObjWeak);
-}
-
-bool NativeInputWindowHandle::updateInfo() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jobject obj = env->NewLocalRef(mObjWeak);
-    if (!obj) {
-        releaseInfo();
-        return false;
-    }
-
-    if (!mInfo) {
-        mInfo = new InputWindowInfo();
-    } else {
-        mInfo->touchableRegion.clear();
-    }
-
-    jobject inputChannelObj = env->GetObjectField(obj,
-            gInputWindowHandleClassInfo.inputChannel);
-    if (inputChannelObj) {
-        mInfo->inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj);
-        env->DeleteLocalRef(inputChannelObj);
-    } else {
-        mInfo->inputChannel.clear();
-    }
-
-    jstring nameObj = jstring(env->GetObjectField(obj,
-            gInputWindowHandleClassInfo.name));
-    if (nameObj) {
-        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
-        mInfo->name = nameStr;
-        env->ReleaseStringUTFChars(nameObj, nameStr);
-        env->DeleteLocalRef(nameObj);
-    } else {
-        mInfo->name = "<null>";
-    }
-
-    mInfo->layoutParamsFlags = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.layoutParamsFlags);
-    mInfo->layoutParamsType = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.layoutParamsType);
-    mInfo->dispatchingTimeout = env->GetLongField(obj,
-            gInputWindowHandleClassInfo.dispatchingTimeoutNanos);
-    mInfo->frameLeft = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.frameLeft);
-    mInfo->frameTop = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.frameTop);
-    mInfo->frameRight = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.frameRight);
-    mInfo->frameBottom = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.frameBottom);
-    mInfo->scaleFactor = env->GetFloatField(obj,
-            gInputWindowHandleClassInfo.scaleFactor);
-
-    jobject regionObj = env->GetObjectField(obj,
-            gInputWindowHandleClassInfo.touchableRegion);
-    if (regionObj) {
-        SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
-        for (SkRegion::Iterator it(*region); !it.done(); it.next()) {
-            const SkIRect& rect = it.rect();
-            mInfo->addTouchableRegion(Rect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom));
-        }
-        env->DeleteLocalRef(regionObj);
-    }
-
-    mInfo->visible = env->GetBooleanField(obj,
-            gInputWindowHandleClassInfo.visible);
-    mInfo->canReceiveKeys = env->GetBooleanField(obj,
-            gInputWindowHandleClassInfo.canReceiveKeys);
-    mInfo->hasFocus = env->GetBooleanField(obj,
-            gInputWindowHandleClassInfo.hasFocus);
-    mInfo->hasWallpaper = env->GetBooleanField(obj,
-            gInputWindowHandleClassInfo.hasWallpaper);
-    mInfo->paused = env->GetBooleanField(obj,
-            gInputWindowHandleClassInfo.paused);
-    mInfo->layer = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.layer);
-    mInfo->ownerPid = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.ownerPid);
-    mInfo->ownerUid = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.ownerUid);
-    mInfo->inputFeatures = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.inputFeatures);
-    mInfo->displayId = env->GetIntField(obj,
-            gInputWindowHandleClassInfo.displayId);
-
-    env->DeleteLocalRef(obj);
-    return true;
-}
-
-
-// --- Global functions ---
-
-sp<NativeInputWindowHandle> android_server_InputWindowHandle_getHandle(
-        JNIEnv* env, jobject inputWindowHandleObj) {
-    if (!inputWindowHandleObj) {
-        return NULL;
-    }
-
-    AutoMutex _l(gHandleMutex);
-
-    jlong ptr = env->GetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr);
-    NativeInputWindowHandle* handle;
-    if (ptr) {
-        handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
-    } else {
-        jobject inputApplicationHandleObj = env->GetObjectField(inputWindowHandleObj,
-                gInputWindowHandleClassInfo.inputApplicationHandle);
-        sp<InputApplicationHandle> inputApplicationHandle =
-                android_server_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
-        env->DeleteLocalRef(inputApplicationHandleObj);
-
-        jweak objWeak = env->NewWeakGlobalRef(inputWindowHandleObj);
-        handle = new NativeInputWindowHandle(inputApplicationHandle, objWeak);
-        handle->incStrong((void*)android_server_InputWindowHandle_getHandle);
-        env->SetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr,
-                reinterpret_cast<jlong>(handle));
-    }
-    return handle;
-}
-
-
-// --- JNI ---
-
-static void android_server_InputWindowHandle_nativeDispose(JNIEnv* env, jobject obj) {
-    AutoMutex _l(gHandleMutex);
-
-    jlong ptr = env->GetLongField(obj, gInputWindowHandleClassInfo.ptr);
-    if (ptr) {
-        env->SetLongField(obj, gInputWindowHandleClassInfo.ptr, 0);
-
-        NativeInputWindowHandle* handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
-        handle->decStrong((void*)android_server_InputWindowHandle_getHandle);
-    }
-}
-
-
-static const JNINativeMethod gInputWindowHandleMethods[] = {
-    /* name, signature, funcPtr */
-    { "nativeDispose", "()V",
-            (void*) android_server_InputWindowHandle_nativeDispose },
-};
-
-#define FIND_CLASS(var, className) \
-        var = env->FindClass(className); \
-        LOG_FATAL_IF(! (var), "Unable to find class " className);
-
-#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
-        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
-        LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
-
-int register_android_server_InputWindowHandle(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputWindowHandle",
-            gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
-    (void) res;  // Faked use when LOG_NDEBUG.
-    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
-
-    jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/input/InputWindowHandle");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz,
-            "ptr", "J");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
-            clazz,
-            "inputApplicationHandle", "Lcom/android/server/input/InputApplicationHandle;");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
-            "inputChannel", "Landroid/view/InputChannel;");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.name, clazz,
-            "name", "Ljava/lang/String;");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz,
-            "layoutParamsFlags", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz,
-            "layoutParamsType", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.dispatchingTimeoutNanos, clazz,
-            "dispatchingTimeoutNanos", "J");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.frameLeft, clazz,
-            "frameLeft", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.frameTop, clazz,
-            "frameTop", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.frameRight, clazz,
-            "frameRight", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.frameBottom, clazz,
-            "frameBottom", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.scaleFactor, clazz,
-            "scaleFactor", "F");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
-            "touchableRegion", "Landroid/graphics/Region;");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
-            "visible", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.canReceiveKeys, clazz,
-            "canReceiveKeys", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.hasFocus, clazz,
-            "hasFocus", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
-            "hasWallpaper", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
-            "paused", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.layer, clazz,
-            "layer", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
-            "ownerPid", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz,
-            "ownerUid", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
-            "inputFeatures", "I");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
-            "displayId", "I");
-    return 0;
-}
-
-} /* namespace android */
diff --git a/services/core/jni/com_android_server_input_InputWindowHandle.h b/services/core/jni/com_android_server_input_InputWindowHandle.h
deleted file mode 100644
index 44d4620..0000000
--- a/services/core/jni/com_android_server_input_InputWindowHandle.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
-#define _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
-
-#include <inputflinger/InputWindow.h>
-
-#include <nativehelper/JNIHelp.h>
-#include "jni.h"
-
-namespace android {
-
-class NativeInputWindowHandle : public InputWindowHandle {
-public:
-    NativeInputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
-            jweak objWeak);
-    virtual ~NativeInputWindowHandle();
-
-    jobject getInputWindowHandleObjLocalRef(JNIEnv* env);
-
-    virtual bool updateInfo();
-
-private:
-    jweak mObjWeak;
-};
-
-
-extern sp<NativeInputWindowHandle> android_server_InputWindowHandle_getHandle(
-        JNIEnv* env, jobject inputWindowHandleObj);
-
-} // namespace android
-
-#endif // _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index b2d35d4..0c9b5f4 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -19,6 +19,7 @@
 //#define LOG_NDEBUG 0
 
 #include <android/hardware/power/1.1/IPower.h>
+#include <android/system/suspend/1.0/ISystemSuspend.h>
 #include <nativehelper/JNIHelp.h>
 #include "jni.h"
 
@@ -35,7 +36,7 @@
 #include <utils/Log.h>
 #include <hardware/power.h>
 #include <hardware_legacy/power.h>
-#include <suspend/autosuspend.h>
+#include <hidl/ServiceManagement.h>
 
 #include "com_android_server_power_PowerManagerService.h"
 
@@ -44,6 +45,9 @@
 using android::hardware::power::V1_0::PowerHint;
 using android::hardware::power::V1_0::Feature;
 using android::String8;
+using android::system::suspend::V1_0::ISystemSuspend;
+using android::system::suspend::V1_0::IWakeLock;
+using android::system::suspend::V1_0::WakeLockType;
 using IPowerV1_1 = android::hardware::power::V1_1::IPower;
 using IPowerV1_0 = android::hardware::power::V1_0::IPower;
 
@@ -171,6 +175,46 @@
     }
 }
 
+static sp<ISystemSuspend> gSuspendHal = nullptr;
+static sp<IWakeLock> gSuspendBlocker = nullptr;
+static std::mutex gSuspendMutex;
+
+// Assume SystemSuspend HAL is always alive.
+// TODO: Force device to restart if SystemSuspend HAL dies.
+sp<ISystemSuspend> getSuspendHal() {
+    static std::once_flag suspendHalFlag;
+    std::call_once(suspendHalFlag, [](){
+        ::android::hardware::details::waitForHwService(ISystemSuspend::descriptor, "default");
+        gSuspendHal = ISystemSuspend::getService();
+        assert(gSuspendHal != nullptr);
+    });
+    return gSuspendHal;
+}
+
+void enableAutoSuspend() {
+    static bool enabled = false;
+
+    std::lock_guard<std::mutex> lock(gSuspendMutex);
+    if (!enabled) {
+        sp<ISystemSuspend> suspendHal = getSuspendHal();
+        suspendHal->enableAutosuspend();
+        enabled = true;
+    }
+    if (gSuspendBlocker) {
+        gSuspendBlocker->release();
+        gSuspendBlocker.clear();
+    }
+}
+
+void disableAutoSuspend() {
+    std::lock_guard<std::mutex> lock(gSuspendMutex);
+    if (!gSuspendBlocker) {
+        sp<ISystemSuspend> suspendHal = getSuspendHal();
+        gSuspendBlocker = suspendHal->acquireWakeLock(WakeLockType::PARTIAL,
+                "PowerManager.SuspendLockout");
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 static void nativeInit(JNIEnv* env, jobject obj) {
@@ -207,13 +251,13 @@
 static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
     if (enable) {
         android::base::Timer t;
-        autosuspend_enable();
+        enableAutoSuspend();
         if (t.duration() > 100ms) {
             ALOGD("Excessive delay in autosuspend_enable() while turning screen off");
         }
     } else {
         android::base::Timer t;
-        autosuspend_disable();
+        disableAutoSuspend();
         if (t.duration() > 100ms) {
             ALOGD("Excessive delay in autosuspend_disable() while turning screen on");
         }
diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/services/core/jni/com_android_server_security_VerityUtils.cpp
new file mode 100644
index 0000000..d0f173b
--- /dev/null
+++ b/services/core/jni/com_android_server_security_VerityUtils.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VerityUtils"
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+#include <utils/Log.h>
+
+#include <string.h>
+
+// TODO(112037636): Always include once fsverity.h is upstreamed and backported.
+#define HAS_FSVERITY 0
+
+#if HAS_FSVERITY
+#include <linux/fsverity.h>
+#endif
+
+namespace android {
+
+namespace {
+
+class JavaByteArrayHolder {
+  public:
+    static JavaByteArrayHolder* newArray(JNIEnv* env, jsize size) {
+        return new JavaByteArrayHolder(env, size);
+    }
+
+    jbyte* getRaw() {
+        return mElements;
+    }
+
+    jbyteArray release() {
+        mEnv->ReleaseByteArrayElements(mBytes, mElements, 0);
+        mElements = nullptr;
+        return mBytes;
+    }
+
+  private:
+    JavaByteArrayHolder(JNIEnv* env, jsize size) {
+        mEnv = env;
+        mBytes = mEnv->NewByteArray(size);
+        mElements = mEnv->GetByteArrayElements(mBytes, nullptr);
+        memset(mElements, 0, size);
+    }
+
+    virtual ~JavaByteArrayHolder() {
+        LOG_ALWAYS_FATAL_IF(mElements == nullptr, "Elements are not released");
+    }
+
+    JNIEnv* mEnv;
+    jbyteArray mBytes;
+    jbyte* mElements;
+};
+
+jbyteArray constructFsverityDescriptor(JNIEnv* env, jobject /* clazz */, jlong fileSize) {
+#if HAS_FSVERITY
+    auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_descriptor));
+    fsverity_descriptor* desc = reinterpret_cast<fsverity_descriptor*>(raii->getRaw());
+
+    memcpy(desc->magic, FS_VERITY_MAGIC, sizeof(desc->magic));
+    desc->major_version = 1;
+    desc->minor_version = 0;
+    desc->log_data_blocksize = 12;
+    desc->log_tree_blocksize = 12;
+    desc->data_algorithm = FS_VERITY_ALG_SHA256;
+    desc->tree_algorithm = FS_VERITY_ALG_SHA256;
+    desc->flags = 0;
+    desc->orig_file_size = fileSize;
+    desc->auth_ext_count = 1;
+
+    return raii->release();
+#else
+    LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
+    return 0;
+#endif  // HAS_FSVERITY
+}
+
+jbyteArray constructFsverityExtension(JNIEnv* env, jobject /* clazz */, jshort extensionId,
+        jint extensionDataSize) {
+#if HAS_FSVERITY
+    auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_extension));
+    fsverity_extension* ext = reinterpret_cast<fsverity_extension*>(raii->getRaw());
+
+    ext->length = sizeof(fsverity_extension) + extensionDataSize;
+    ext->type = extensionId;
+
+    return raii->release();
+#else
+    LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
+    return 0;
+#endif  // HAS_FSVERITY
+}
+
+jbyteArray constructFsverityFooter(JNIEnv* env, jobject /* clazz */,
+        jint offsetToDescriptorHead) {
+#if HAS_FSVERITY
+    auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_footer));
+    fsverity_footer* footer = reinterpret_cast<fsverity_footer*>(raii->getRaw());
+
+    footer->desc_reverse_offset = offsetToDescriptorHead + sizeof(fsverity_footer);
+    memcpy(footer->magic, FS_VERITY_MAGIC, sizeof(footer->magic));
+
+    return raii->release();
+#else
+    LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
+    return 0;
+#endif  // HAS_FSVERITY
+}
+
+const JNINativeMethod sMethods[] = {
+    { "constructFsverityDescriptorNative", "(J)[B", (void *)constructFsverityDescriptor },
+    { "constructFsverityExtensionNative", "(SI)[B", (void *)constructFsverityExtension },
+    { "constructFsverityFooterNative", "(I)[B", (void *)constructFsverityFooter },
+};
+
+}  // namespace
+
+int register_android_server_security_VerityUtils(JNIEnv* env) {
+    return jniRegisterNativeMethods(env,
+            "com/android/server/security/VerityUtils", sMethods, NELEM(sMethods));
+}
+
+}  // namespace android
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index 93c4829..6c2a894 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -390,7 +390,11 @@
                 [&result, &sidebandStream](Result res, const native_handle_t* handle) {
                     result = res;
                     if (res == Result::OK) {
-                        sidebandStream = handle;
+                        if (handle) {
+                            sidebandStream = native_handle_clone(handle);
+                        } else {
+                            result = Result::UNKNOWN;
+                        }
                     }
                 });
         if (result != Result::OK) {
@@ -398,7 +402,7 @@
                     result);
             return UNKNOWN_ERROR;
         }
-        connection.mSourceHandle = NativeHandle::create((native_handle_t*)sidebandStream, false);
+        connection.mSourceHandle = NativeHandle::create((native_handle_t*)sidebandStream, true);
     }
     connection.mSurface = surface;
     if (connection.mSurface != nullptr) {
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index bb6e684..918f57e 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -54,6 +54,7 @@
 int register_android_server_GraphicsStatsService(JNIEnv* env);
 int register_android_hardware_display_DisplayViewport(JNIEnv* env);
 int register_android_server_net_NetworkStatsService(JNIEnv* env);
+int register_android_server_security_VerityUtils(JNIEnv* env);
 };
 
 using namespace android;
@@ -101,5 +102,6 @@
     register_android_server_GraphicsStatsService(env);
     register_android_hardware_display_DisplayViewport(env);
     register_android_server_net_NetworkStatsService(env);
+    register_android_server_security_VerityUtils(env);
     return JNI_VERSION_1_4;
 }
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..66cf48c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -15,20 +15,10 @@
  */
 package com.android.server.devicepolicy;
 
-import android.annotation.UserIdInt;
 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 +54,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;
     }
@@ -160,8 +66,4 @@
     public long forceSecurityLogs() {
         return 0;
     }
-
-    @Override
-    public void setDefaultSmsApplication(ComponentName admin, String packageName) {
-    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
index 0c0ce8d..85ca52e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
@@ -18,27 +18,23 @@
 import android.Manifest.permission;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.DeviceAdminService;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDeviceAdminService;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.am.PersistentConnection;
+import com.android.server.appbinding.AppBindingUtils;
 
 import java.io.PrintWriter;
-import java.util.List;
 
 /**
  * Manages connections to persistent services in owner packages.
@@ -70,7 +66,13 @@
             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
+        protected int getBindFlags() {
+            return Context.BIND_FOREGROUND_SERVICE;
         }
 
         @Override
@@ -100,40 +102,14 @@
      */
     @Nullable
     private ServiceInfo findService(@NonNull String packageName, int userId) {
-        final Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE);
-        intent.setPackage(packageName);
-
-        try {
-            final ParceledListSlice<ResolveInfo> pls = mInjector.getIPackageManager()
-                    .queryIntentServices(intent, null, /* flags=*/ 0, userId);
-            if (pls == null) {
-                return null;
-            }
-            final List<ResolveInfo> list = pls.getList();
-            if (list.size() == 0) {
-                return null;
-            }
-            // Note if multiple services are found, that's an error, even if only one of them
-            // is exported.
-            if (list.size() > 1) {
-                Log.e(TAG, "More than one DeviceAdminService's found in package "
-                        + packageName
-                        + ".  They'll all be ignored.");
-                return null;
-            }
-            final ServiceInfo si = list.get(0).serviceInfo;
-
-            if (!permission.BIND_DEVICE_ADMIN.equals(si.permission)) {
-                Log.e(TAG, "DeviceAdminService "
-                        + si.getComponentName().flattenToShortString()
-                        + " must be protected with " + permission.BIND_DEVICE_ADMIN
-                        + ".");
-                return null;
-            }
-            return si;
-        } catch (RemoteException e) {
-        }
-        return null;
+        return AppBindingUtils.findService(
+                packageName,
+                userId,
+                DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE,
+                permission.BIND_DEVICE_ADMIN,
+                DeviceAdminService.class,
+                mInjector.getIPackageManager(),
+                new StringBuilder() /* ignore error message */);
     }
 
     /**
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 4c71d65..eeb4ad3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6019,7 +6019,7 @@
             success = mUserManagerInternal.removeUserEvenWhenDisallowed(userId);
             if (!success) {
                 Slog.w(LOG_TAG, "Couldn't remove user " + userId);
-            } else if (isManagedProfile(userId)) {
+            } else if (isManagedProfile(userId) && !TextUtils.isEmpty(wipeReasonForUser)) {
                 sendWipeProfileNotification(wipeReasonForUser);
             }
         } catch (RemoteException re) {
@@ -6034,7 +6034,6 @@
         if (!mHasFeature) {
             return;
         }
-        Preconditions.checkStringNotEmpty(wipeReasonForUser, "wipeReasonForUser is null or empty");
         enforceFullCrossUsersPermission(mInjector.userHandleGetCallingUserId());
 
         final ActiveAdmin admin;
@@ -10107,13 +10106,15 @@
             if (setting.equals(Settings.Secure.INSTALL_NON_MARKET_APPS)) {
                 if (getTargetSdk(who.getPackageName(), callingUserId) >= Build.VERSION_CODES.O) {
                     throw new UnsupportedOperationException(Settings.Secure.INSTALL_NON_MARKET_APPS
-                            + " is deprecated. Please use the user restriction "
-                            + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES + " instead.");
+                            + " is deprecated. Please use one of the user restrictions "
+                            + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES + " or "
+                            + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY + " instead.");
                 }
                 if (!mUserManager.isManagedProfile(callingUserId)) {
                     Slog.e(LOG_TAG, "Ignoring setSecureSetting request for "
                             + setting + ". User restriction "
-                            + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES
+                            + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES + " or "
+                            + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY
                             + " should be used instead.");
                 } else {
                     try {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9d63305..52b849f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -63,11 +63,11 @@
 import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.EmergencyAffordanceManager;
 import com.android.internal.widget.ILockSettings;
-import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.ActivityTaskManagerService;
+import com.android.server.appbinding.AppBindingService;
 import com.android.server.audio.AudioService;
-import com.android.server.biometrics.BiometricPromptService;
+import com.android.server.biometrics.BiometricService;
 import com.android.server.broadcastradio.BroadcastRadioService;
 import com.android.server.camera.CameraServiceProxy;
 import com.android.server.clipboard.ClipboardService;
@@ -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;
@@ -1590,7 +1590,7 @@
             if (hasFeatureFace || hasFeatureFingerprint) {
                 // Start this service after all biometric services.
                 traceBeginAndSlog("StartBiometricPromptService");
-                mSystemServiceManager.startService(BiometricPromptService.class);
+                mSystemServiceManager.startService(BiometricService.class);
                 traceEnd();
             }
 
@@ -1711,6 +1711,10 @@
             traceEnd();
         }
 
+        traceBeginAndSlog("AppServiceManager");
+        mSystemServiceManager.startService(AppBindingService.Lifecycle.class);
+        traceEnd();
+
         // It is now time to start up the app processes...
 
         traceBeginAndSlog("MakeVibratorServiceReady");
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/netlink/InetDiagMessage.java b/services/net/java/android/net/netlink/InetDiagMessage.java
new file mode 100644
index 0000000..af9e601
--- /dev/null
+++ b/services/net/java/android/net/netlink/InetDiagMessage.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.netlink;
+
+import static android.os.Process.INVALID_UID;
+import static android.net.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY;
+import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.NETLINK_INET_DIAG;
+
+import android.os.Build;
+import android.os.Process;
+import android.system.ErrnoException;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
+import java.net.DatagramSocket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * A NetlinkMessage subclass for netlink inet_diag messages.
+ *
+ * see also: &lt;linux_src&gt;/include/uapi/linux/inet_diag.h
+ *
+ * @hide
+ */
+public class InetDiagMessage extends NetlinkMessage {
+    public static final String TAG = "InetDiagMessage";
+    private static final int TIMEOUT_MS = 500;
+
+    public static byte[] InetDiagReqV2(int protocol, InetSocketAddress local,
+                                       InetSocketAddress remote, int family, short flags) {
+        final byte[] bytes = new byte[StructNlMsgHdr.STRUCT_SIZE + StructInetDiagReqV2.STRUCT_SIZE];
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+        byteBuffer.order(ByteOrder.nativeOrder());
+
+        final StructNlMsgHdr nlMsgHdr = new StructNlMsgHdr();
+        nlMsgHdr.nlmsg_len = bytes.length;
+        nlMsgHdr.nlmsg_type = SOCK_DIAG_BY_FAMILY;
+        nlMsgHdr.nlmsg_flags = flags;
+        nlMsgHdr.pack(byteBuffer);
+
+        final StructInetDiagReqV2 inetDiagReqV2 = new StructInetDiagReqV2(protocol, local, remote,
+                family);
+        inetDiagReqV2.pack(byteBuffer);
+        return bytes;
+    }
+
+    public StructInetDiagMsg mStructInetDiagMsg;
+
+    private InetDiagMessage(StructNlMsgHdr header) {
+        super(header);
+        mStructInetDiagMsg = new StructInetDiagMsg();
+    }
+
+    public static InetDiagMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
+        final InetDiagMessage msg = new InetDiagMessage(header);
+        msg.mStructInetDiagMsg = StructInetDiagMsg.parse(byteBuffer);
+        return msg;
+    }
+
+    private static int lookupUidByFamily(int protocol, InetSocketAddress local,
+                                         InetSocketAddress remote, int family, short flags,
+                                         FileDescriptor fd)
+            throws ErrnoException, InterruptedIOException {
+        byte[] msg = InetDiagReqV2(protocol, local, remote, family, flags);
+        NetlinkSocket.sendMessage(fd, msg, 0, msg.length, TIMEOUT_MS);
+        ByteBuffer response = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT_MS);
+
+        final NetlinkMessage nlMsg = NetlinkMessage.parse(response);
+        final StructNlMsgHdr hdr = nlMsg.getHeader();
+        if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) {
+            return INVALID_UID;
+        }
+        if (nlMsg instanceof InetDiagMessage) {
+            return ((InetDiagMessage) nlMsg).mStructInetDiagMsg.idiag_uid;
+        }
+        return INVALID_UID;
+    }
+
+    private static final int FAMILY[] = {AF_INET6, AF_INET};
+
+    private static int lookupUid(int protocol, InetSocketAddress local,
+                                 InetSocketAddress remote, FileDescriptor fd)
+            throws ErrnoException, InterruptedIOException {
+        int uid;
+
+        for (int family : FAMILY) {
+            /**
+             * For exact match lookup, swap local and remote for UDP lookups due to kernel
+             * bug which will not be fixed. See aosp/755889 and
+             * https://www.mail-archive.com/netdev@vger.kernel.org/msg248638.html
+             */
+            if (protocol == IPPROTO_UDP) {
+                uid = lookupUidByFamily(protocol, remote, local, family, NLM_F_REQUEST, fd);
+            } else {
+                uid = lookupUidByFamily(protocol, local, remote, family, NLM_F_REQUEST, fd);
+            }
+            if (uid != INVALID_UID) {
+                return uid;
+            }
+        }
+
+        /**
+         * For UDP it's possible for a socket to send packets to arbitrary destinations, even if the
+         * socket is not connected (and even if the socket is connected to a different destination).
+         * If we want this API to work for such packets, then on miss we need to do a second lookup
+         * with only the local address and port filled in.
+         * Always use flags == NLM_F_REQUEST | NLM_F_DUMP for wildcard.
+         */
+        if (protocol == IPPROTO_UDP) {
+            try {
+                InetSocketAddress wildcard = new InetSocketAddress(
+                        Inet6Address.getByName("::"), 0);
+                uid = lookupUidByFamily(protocol, local, wildcard, AF_INET6,
+                        (short) (NLM_F_REQUEST | NLM_F_DUMP), fd);
+                if (uid != INVALID_UID) {
+                    return uid;
+                }
+                wildcard = new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), 0);
+                uid = lookupUidByFamily(protocol, local, wildcard, AF_INET,
+                        (short) (NLM_F_REQUEST | NLM_F_DUMP), fd);
+                if (uid != INVALID_UID) {
+                    return uid;
+                }
+            } catch (UnknownHostException e) {
+                Log.e(TAG, e.toString());
+            }
+        }
+        return INVALID_UID;
+    }
+
+    /**
+     * Use an inet_diag socket to look up the UID associated with the input local and remote
+     * address/port and protocol of a connection.
+     */
+    public static int getConnectionOwnerUid(int protocol, InetSocketAddress local,
+                                            InetSocketAddress remote) {
+        try {
+            final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_INET_DIAG);
+            NetlinkSocket.connectToKernel(fd);
+
+            return lookupUid(protocol, local, remote, fd);
+
+        } catch (ErrnoException | SocketException | IllegalArgumentException
+                | InterruptedIOException e) {
+            Log.e(TAG, e.toString());
+        }
+        return INVALID_UID;
+    }
+
+    @Override
+    public String toString() {
+        return "InetDiagMessage{ "
+                + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, "
+                + "inet_diag_msg{"
+                + (mStructInetDiagMsg == null ? "" : mStructInetDiagMsg.toString()) + "} "
+                + "}";
+    }
+}
diff --git a/services/net/java/android/net/netlink/NetlinkConstants.java b/services/net/java/android/net/netlink/NetlinkConstants.java
index e331701..fc1551c 100644
--- a/services/net/java/android/net/netlink/NetlinkConstants.java
+++ b/services/net/java/android/net/netlink/NetlinkConstants.java
@@ -54,6 +54,12 @@
         return String.valueOf(family);
     }
 
+    public static String stringForProtocol(int protocol) {
+        if (protocol == OsConstants.IPPROTO_TCP) { return "IPPROTO_TCP"; }
+        if (protocol == OsConstants.IPPROTO_UDP) { return "IPPROTO_UDP"; }
+        return String.valueOf(protocol);
+    }
+
     public static String hexify(byte[] bytes) {
         if (bytes == null) { return "(null)"; }
         return HexDump.toHexString(bytes);
@@ -90,6 +96,9 @@
     public static final short RTM_GETRULE        = 34;
     public static final short RTM_NEWNDUSEROPT   = 68;
 
+    /* see &lt;linux_src&gt;/include/uapi/linux/sock_diag.h */
+    public static final short SOCK_DIAG_BY_FAMILY = 20;
+
     public static String stringForNlMsgType(short nlm_type) {
         switch (nlm_type) {
             case NLMSG_NOOP: return "NLMSG_NOOP";
diff --git a/services/net/java/android/net/netlink/NetlinkMessage.java b/services/net/java/android/net/netlink/NetlinkMessage.java
index 3bf75ca..a325db8 100644
--- a/services/net/java/android/net/netlink/NetlinkMessage.java
+++ b/services/net/java/android/net/netlink/NetlinkMessage.java
@@ -69,6 +69,8 @@
             case NetlinkConstants.RTM_DELNEIGH:
             case NetlinkConstants.RTM_GETNEIGH:
                 return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer);
+            case NetlinkConstants.SOCK_DIAG_BY_FAMILY:
+                return (NetlinkMessage) InetDiagMessage.parse(nlmsghdr, byteBuffer);
             default:
                 if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) {
                     // Netlink control message.  Just parse the header for now,
diff --git a/services/net/java/android/net/netlink/StructInetDiagMsg.java b/services/net/java/android/net/netlink/StructInetDiagMsg.java
new file mode 100644
index 0000000..da824ad
--- /dev/null
+++ b/services/net/java/android/net/netlink/StructInetDiagMsg.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.netlink;
+
+import static java.nio.ByteOrder.BIG_ENDIAN;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import java.net.Inet4Address;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import android.util.Log;
+
+/**
+ * struct inet_diag_msg
+ *
+ * see &lt;linux_src&gt;/include/uapi/linux/inet_diag.h
+ *
+ * struct inet_diag_msg {
+ *      __u8    idiag_family;
+ *      __u8    idiag_state;
+ *      __u8    idiag_timer;
+ *      __u8    idiag_retrans;
+ *      struct  inet_diag_sockid id;
+ *      __u32   idiag_expires;
+ *      __u32   idiag_rqueue;
+ *      __u32   idiag_wqueue;
+ *      __u32   idiag_uid;
+ *      __u32   idiag_inode;
+ * };
+ *
+ * @hide
+ */
+public class StructInetDiagMsg {
+    public static final int STRUCT_SIZE = 4 + StructInetDiagSockId.STRUCT_SIZE + 20;
+    private static final int IDIAG_UID_OFFSET = StructNlMsgHdr.STRUCT_SIZE + 4 +
+            StructInetDiagSockId.STRUCT_SIZE + 12;
+    public int idiag_uid;
+
+    public static StructInetDiagMsg parse(ByteBuffer byteBuffer) {
+        StructInetDiagMsg struct = new StructInetDiagMsg();
+        struct.idiag_uid = byteBuffer.getInt(IDIAG_UID_OFFSET);
+        return struct;
+    }
+
+    @Override
+    public String toString() {
+        return "StructInetDiagMsg{ "
+                + "idiag_uid{" + idiag_uid + "}, "
+                + "}";
+    }
+}
diff --git a/services/net/java/android/net/netlink/StructInetDiagReqV2.java b/services/net/java/android/net/netlink/StructInetDiagReqV2.java
new file mode 100644
index 0000000..49a9325
--- /dev/null
+++ b/services/net/java/android/net/netlink/StructInetDiagReqV2.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.net.netlink;
+
+import static java.nio.ByteOrder.BIG_ENDIAN;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * struct inet_diag_req_v2
+ *
+ * see &lt;linux_src&gt;/include/uapi/linux/inet_diag.h
+ *
+ *      struct inet_diag_req_v2 {
+ *          __u8    sdiag_family;
+ *          __u8    sdiag_protocol;
+ *          __u8    idiag_ext;
+ *          __u8    pad;
+ *          __u32   idiag_states;
+ *          struct  inet_diag_sockid id;
+ *      };
+ *
+ * @hide
+ */
+public class StructInetDiagReqV2 {
+    public static final int STRUCT_SIZE = 8 + StructInetDiagSockId.STRUCT_SIZE;
+
+    private final byte sdiag_family;
+    private final byte sdiag_protocol;
+    private final StructInetDiagSockId id;
+    private final int INET_DIAG_REQ_V2_ALL_STATES = (int) 0xffffffff;
+
+
+    public StructInetDiagReqV2(int protocol, InetSocketAddress local, InetSocketAddress remote,
+                               int family) {
+        sdiag_family = (byte) family;
+        sdiag_protocol = (byte) protocol;
+        id = new StructInetDiagSockId(local, remote);
+    }
+
+    public void pack(ByteBuffer byteBuffer) {
+        // The ByteOrder must have already been set by the caller.
+        byteBuffer.put((byte) sdiag_family);
+        byteBuffer.put((byte) sdiag_protocol);
+        byteBuffer.put((byte) 0);
+        byteBuffer.put((byte) 0);
+        byteBuffer.putInt(INET_DIAG_REQ_V2_ALL_STATES);
+        id.pack(byteBuffer);
+    }
+
+    @Override
+    public String toString() {
+        final String familyStr = NetlinkConstants.stringForAddressFamily(sdiag_family);
+        final String protocolStr = NetlinkConstants.stringForAddressFamily(sdiag_protocol);
+
+        return "StructInetDiagReqV2{ "
+                + "sdiag_family{" + familyStr + "}, "
+                + "sdiag_protocol{" + protocolStr + "}, "
+                + "idiag_ext{" + 0 + ")}, "
+                + "pad{" + 0 + "}, "
+                + "idiag_states{" + Integer.toHexString(INET_DIAG_REQ_V2_ALL_STATES) + "}, "
+                + id.toString()
+                + "}";
+    }
+}
diff --git a/services/net/java/android/net/netlink/StructInetDiagSockId.java b/services/net/java/android/net/netlink/StructInetDiagSockId.java
new file mode 100644
index 0000000..2e9fa25
--- /dev/null
+++ b/services/net/java/android/net/netlink/StructInetDiagSockId.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.netlink;
+
+import static java.nio.ByteOrder.BIG_ENDIAN;
+
+import java.net.Inet4Address;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * struct inet_diag_req_v2
+ *
+ * see &lt;linux_src&gt;/include/uapi/linux/inet_diag.h
+ *
+ * struct inet_diag_sockid {
+ *        __be16    idiag_sport;
+ *        __be16    idiag_dport;
+ *        __be32    idiag_src[4];
+ *        __be32    idiag_dst[4];
+ *        __u32     idiag_if;
+ *        __u32     idiag_cookie[2];
+ * #define INET_DIAG_NOCOOKIE (~0U)
+ * };
+ *
+ * @hide
+ */
+public class StructInetDiagSockId {
+    public static final int STRUCT_SIZE = 48;
+
+    private final InetSocketAddress mLocSocketAddress;
+    private final InetSocketAddress mRemSocketAddress;
+    private final byte[] INET_DIAG_NOCOOKIE = new byte[]{
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+    private final byte[] IPV4_PADDING = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+    public StructInetDiagSockId(InetSocketAddress loc, InetSocketAddress rem) {
+        mLocSocketAddress = loc;
+        mRemSocketAddress = rem;
+    }
+
+    public void pack(ByteBuffer byteBuffer) {
+        byteBuffer.order(BIG_ENDIAN);
+        byteBuffer.putShort((short) mLocSocketAddress.getPort());
+        byteBuffer.putShort((short) mRemSocketAddress.getPort());
+        byteBuffer.put(mLocSocketAddress.getAddress().getAddress());
+        if (mLocSocketAddress.getAddress() instanceof Inet4Address) {
+            byteBuffer.put(IPV4_PADDING);
+        }
+        byteBuffer.put(mRemSocketAddress.getAddress().getAddress());
+        if (mRemSocketAddress.getAddress() instanceof Inet4Address) {
+            byteBuffer.put(IPV4_PADDING);
+        }
+        byteBuffer.order(ByteOrder.nativeOrder());
+        byteBuffer.putInt(0);
+        byteBuffer.put(INET_DIAG_NOCOOKIE);
+    }
+
+    @Override
+    public String toString() {
+        return "StructInetDiagSockId{ "
+                + "idiag_sport{" + mLocSocketAddress.getPort() + "}, "
+                + "idiag_dport{" + mRemSocketAddress.getPort() + "}, "
+                + "idiag_src{" + mLocSocketAddress.getAddress().getHostAddress() + "}, "
+                + "idiag_dst{" + mRemSocketAddress.getAddress().getHostAddress() + "}, "
+                + "idiag_if{" + 0 + "} "
+                + "idiag_cookie{INET_DIAG_NOCOOKIE}"
+                + "}";
+    }
+}
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
index f7bf393..5a73a4e 100644
--- a/services/net/java/android/net/util/SharedLog.java
+++ b/services/net/java/android/net/util/SharedLog.java
@@ -17,6 +17,7 @@
 package android.net.util;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
@@ -92,10 +93,17 @@
     }
 
     /**
-     * Log an error due to an exception, with the exception stacktrace.
+     * Log an error due to an exception, with the exception stacktrace if provided.
+     *
+     * <p>The error and exception message appear in the shared log, but the stacktrace is only
+     * logged in general log output (logcat).
      */
-    public void e(@NonNull String msg, @NonNull Throwable e) {
-        Log.e(mTag, record(Category.ERROR, msg + ": " + e.getMessage()), e);
+    public void e(@NonNull String msg, @Nullable Throwable exception) {
+        if (exception == null) {
+            e(msg);
+            return;
+        }
+        Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception);
     }
 
     public void i(String msg) {
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index 8b59771..78c0be4 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -61,6 +61,7 @@
     $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \
     $(call all-java-files-under, ../../core/java/android/app/backup) \
     $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \
+    $(call all-java-files-under, ../../core/java/android/util/proto) \
     ../../core/java/android/content/pm/PackageInfo.java \
     ../../core/java/android/app/IBackupAgent.aidl \
     ../../core/java/android/util/KeyValueSettingObserver.java \
diff --git a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
index 57ebbfc..de915ab 100644
--- a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -122,6 +122,13 @@
         ShadowAppBackupUtils.reset();
     }
 
+    @Test
+    public void testMoreDebug_isFalse() throws Exception {
+        boolean moreDebug = BackupManagerService.MORE_DEBUG;
+
+        assertThat(moreDebug).isFalse();
+    }
+
     /* Tests for destination string */
 
     @Test
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java
new file mode 100644
index 0000000..383bf1d
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import com.android.internal.util.Preconditions;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import com.google.common.base.Charsets;
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+// Include android.util.proto in addition to classes under test because the latest versions of
+// android.util.proto.Proto{Input|Output}Stream are not part of Robolectric.
+@SystemLoaderPackages({"com.android.server.backup", "android.util.proto"})
+@Presubmit
+public class ChunkListingTest {
+    private static final String CHUNK_A = "CHUNK_A";
+    private static final String CHUNK_B = "CHUNK_B";
+    private static final String CHUNK_C = "CHUNK_C";
+
+    private static final int CHUNK_A_LENGTH = 256;
+    private static final int CHUNK_B_LENGTH = 1024;
+    private static final int CHUNK_C_LENGTH = 4055;
+
+    private ChunkHash mChunkHashA;
+    private ChunkHash mChunkHashB;
+    private ChunkHash mChunkHashC;
+
+    @Before
+    public void setUp() throws Exception {
+        mChunkHashA = getHash(CHUNK_A);
+        mChunkHashB = getHash(CHUNK_B);
+        mChunkHashC = getHash(CHUNK_C);
+    }
+
+    @Test
+    public void testHasChunk_whenChunkInListing_returnsTrue() throws Exception {
+        byte[] chunkListingProto =
+                createChunkListingProto(
+                        new ChunkHash[] {mChunkHashA, mChunkHashB, mChunkHashC},
+                        new int[] {CHUNK_A_LENGTH, CHUNK_B_LENGTH, CHUNK_C_LENGTH});
+        ChunkListing chunkListing =
+                ChunkListing.readFromProto(
+                        new ProtoInputStream(new ByteArrayInputStream(chunkListingProto)));
+
+        boolean chunkAInList = chunkListing.hasChunk(mChunkHashA);
+        boolean chunkBInList = chunkListing.hasChunk(mChunkHashB);
+        boolean chunkCInList = chunkListing.hasChunk(mChunkHashC);
+
+        assertThat(chunkAInList).isTrue();
+        assertThat(chunkBInList).isTrue();
+        assertThat(chunkCInList).isTrue();
+    }
+
+    @Test
+    public void testHasChunk_whenChunkNotInListing_returnsFalse() throws Exception {
+        byte[] chunkListingProto =
+                createChunkListingProto(
+                        new ChunkHash[] {mChunkHashA, mChunkHashB},
+                        new int[] {CHUNK_A_LENGTH, CHUNK_B_LENGTH});
+        ChunkListing chunkListing =
+                ChunkListing.readFromProto(
+                        new ProtoInputStream(new ByteArrayInputStream(chunkListingProto)));
+        ChunkHash chunkHashEmpty = getHash("");
+
+        boolean chunkCInList = chunkListing.hasChunk(mChunkHashC);
+        boolean emptyChunkInList = chunkListing.hasChunk(chunkHashEmpty);
+
+        assertThat(chunkCInList).isFalse();
+        assertThat(emptyChunkInList).isFalse();
+    }
+
+    @Test
+    public void testGetChunkEntry_returnsEntryWithCorrectLength() throws Exception {
+        byte[] chunkListingProto =
+                createChunkListingProto(
+                        new ChunkHash[] {mChunkHashA, mChunkHashB, mChunkHashC},
+                        new int[] {CHUNK_A_LENGTH, CHUNK_B_LENGTH, CHUNK_C_LENGTH});
+        ChunkListing chunkListing =
+                ChunkListing.readFromProto(
+                        new ProtoInputStream(new ByteArrayInputStream(chunkListingProto)));
+
+        ChunkListing.Entry entryA = chunkListing.getChunkEntry(mChunkHashA);
+        ChunkListing.Entry entryB = chunkListing.getChunkEntry(mChunkHashB);
+        ChunkListing.Entry entryC = chunkListing.getChunkEntry(mChunkHashC);
+
+        assertThat(entryA.getLength()).isEqualTo(CHUNK_A_LENGTH);
+        assertThat(entryB.getLength()).isEqualTo(CHUNK_B_LENGTH);
+        assertThat(entryC.getLength()).isEqualTo(CHUNK_C_LENGTH);
+    }
+
+    @Test
+    public void testGetChunkEntry_returnsEntryWithCorrectStart() throws Exception {
+        byte[] chunkListingProto =
+                createChunkListingProto(
+                        new ChunkHash[] {mChunkHashA, mChunkHashB, mChunkHashC},
+                        new int[] {CHUNK_A_LENGTH, CHUNK_B_LENGTH, CHUNK_C_LENGTH});
+        ChunkListing chunkListing =
+                ChunkListing.readFromProto(
+                        new ProtoInputStream(new ByteArrayInputStream(chunkListingProto)));
+
+        ChunkListing.Entry entryA = chunkListing.getChunkEntry(mChunkHashA);
+        ChunkListing.Entry entryB = chunkListing.getChunkEntry(mChunkHashB);
+        ChunkListing.Entry entryC = chunkListing.getChunkEntry(mChunkHashC);
+
+        assertThat(entryA.getStart()).isEqualTo(0);
+        assertThat(entryB.getStart()).isEqualTo(CHUNK_A_LENGTH);
+        assertThat(entryC.getStart()).isEqualTo(CHUNK_A_LENGTH + CHUNK_B_LENGTH);
+    }
+
+    @Test
+    public void testGetChunkEntry_returnsNullForNonExistentChunk() throws Exception {
+        byte[] chunkListingProto =
+                createChunkListingProto(
+                        new ChunkHash[] {mChunkHashA, mChunkHashB},
+                        new int[] {CHUNK_A_LENGTH, CHUNK_B_LENGTH});
+        ChunkListing chunkListing =
+                ChunkListing.readFromProto(
+                        new ProtoInputStream(new ByteArrayInputStream(chunkListingProto)));
+
+        ChunkListing.Entry chunkEntryNonexistentChunk = chunkListing.getChunkEntry(mChunkHashC);
+
+        assertThat(chunkEntryNonexistentChunk).isNull();
+    }
+
+    @Test
+    public void testReadFromProto_whenEmptyProto_returnsChunkListingWith0Chunks() throws Exception {
+        ProtoInputStream emptyProto = new ProtoInputStream(new ByteArrayInputStream(new byte[] {}));
+
+        ChunkListing chunkListing = ChunkListing.readFromProto(emptyProto);
+
+        assertThat(chunkListing.getChunkCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testReadFromProto_returnsChunkListingWithCorrectSize() throws Exception {
+        byte[] chunkListingProto =
+                createChunkListingProto(
+                        new ChunkHash[] {mChunkHashA, mChunkHashB, mChunkHashC},
+                        new int[] {CHUNK_A_LENGTH, CHUNK_B_LENGTH, CHUNK_C_LENGTH});
+
+        ChunkListing chunkListing =
+                ChunkListing.readFromProto(
+                        new ProtoInputStream(new ByteArrayInputStream(chunkListingProto)));
+
+        assertThat(chunkListing.getChunkCount()).isEqualTo(3);
+    }
+
+    private byte[] createChunkListingProto(ChunkHash[] hashes, int[] lengths) {
+        Preconditions.checkArgument(hashes.length == lengths.length);
+        ProtoOutputStream outputStream = new ProtoOutputStream();
+
+        for (int i = 0; i < hashes.length; ++i) {
+            writeToProtoOutputStream(outputStream, hashes[i], lengths[i]);
+        }
+        outputStream.flush();
+
+        return outputStream.getBytes();
+    }
+
+    private void writeToProtoOutputStream(ProtoOutputStream out, ChunkHash chunkHash, int length) {
+        long token = out.start(ChunksMetadataProto.ChunkListing.CHUNKS);
+        out.write(ChunksMetadataProto.Chunk.HASH, chunkHash.getHash());
+        out.write(ChunksMetadataProto.Chunk.LENGTH, length);
+        out.end(token);
+    }
+
+    private ChunkHash getHash(String name) {
+        return new ChunkHash(
+                Arrays.copyOf(name.getBytes(Charsets.UTF_8), ChunkHash.HASH_LENGTH_BYTES));
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java
new file mode 100644
index 0000000..1dd7dc8
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import com.google.common.base.Charsets;
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+// Include android.util.proto in addition to classes under test because the latest versions of
+// android.util.proto.Proto{Input|Output}Stream are not part of Robolectric.
+@SystemLoaderPackages({"com.android.server.backup", "android.util.proto"})
+@Presubmit
+public class ChunkTest {
+    private static final String CHUNK_A = "CHUNK_A";
+    private static final int CHUNK_A_LENGTH = 256;
+
+    private ChunkHash mChunkHashA;
+
+    @Before
+    public void setUp() throws Exception {
+        mChunkHashA = getHash(CHUNK_A);
+    }
+
+    @Test
+    public void testReadFromProto_readsCorrectly() throws Exception {
+        ProtoOutputStream out = new ProtoOutputStream();
+        out.write(ChunksMetadataProto.Chunk.HASH, mChunkHashA.getHash());
+        out.write(ChunksMetadataProto.Chunk.LENGTH, CHUNK_A_LENGTH);
+        out.flush();
+        byte[] protoBytes = out.getBytes();
+
+        Chunk chunk =
+                Chunk.readFromProto(new ProtoInputStream(new ByteArrayInputStream(protoBytes)));
+
+        assertThat(chunk.getHash()).isEqualTo(mChunkHashA.getHash());
+        assertThat(chunk.getLength()).isEqualTo(CHUNK_A_LENGTH);
+    }
+
+    @Test
+    public void testReadFromProto_whenFieldsWrittenInReversedOrder_readsCorrectly()
+            throws Exception {
+        ProtoOutputStream out = new ProtoOutputStream();
+        // Write fields of Chunk proto in reverse order.
+        out.write(ChunksMetadataProto.Chunk.LENGTH, CHUNK_A_LENGTH);
+        out.write(ChunksMetadataProto.Chunk.HASH, mChunkHashA.getHash());
+        out.flush();
+        byte[] protoBytes = out.getBytes();
+
+        Chunk chunk =
+                Chunk.readFromProto(new ProtoInputStream(new ByteArrayInputStream(protoBytes)));
+
+        assertThat(chunk.getHash()).isEqualTo(mChunkHashA.getHash());
+        assertThat(chunk.getLength()).isEqualTo(CHUNK_A_LENGTH);
+    }
+
+    @Test
+    public void testReadFromProto_whenEmptyProto_returnsEmptyHash() throws Exception {
+        ProtoInputStream emptyProto = new ProtoInputStream(new ByteArrayInputStream(new byte[] {}));
+
+        Chunk chunk = Chunk.readFromProto(emptyProto);
+
+        assertThat(chunk.getHash()).asList().hasSize(0);
+        assertThat(chunk.getLength()).isEqualTo(0);
+    }
+
+    @Test
+    public void testReadFromProto_whenOnlyHashSet_returnsChunkWithOnlyHash() throws Exception {
+        ProtoOutputStream out = new ProtoOutputStream();
+        out.write(ChunksMetadataProto.Chunk.HASH, mChunkHashA.getHash());
+        out.flush();
+        byte[] protoBytes = out.getBytes();
+
+        Chunk chunk =
+                Chunk.readFromProto(new ProtoInputStream(new ByteArrayInputStream(protoBytes)));
+
+        assertThat(chunk.getHash()).isEqualTo(mChunkHashA.getHash());
+        assertThat(chunk.getLength()).isEqualTo(0);
+    }
+
+    @Test
+    public void testReadFromProto_whenOnlyLengthSet_returnsChunkWithOnlyLength() throws Exception {
+        ProtoOutputStream out = new ProtoOutputStream();
+        out.write(ChunksMetadataProto.Chunk.LENGTH, CHUNK_A_LENGTH);
+        out.flush();
+        byte[] protoBytes = out.getBytes();
+
+        Chunk chunk =
+                Chunk.readFromProto(new ProtoInputStream(new ByteArrayInputStream(protoBytes)));
+
+        assertThat(chunk.getHash()).isEqualTo(new byte[] {});
+        assertThat(chunk.getLength()).isEqualTo(CHUNK_A_LENGTH);
+    }
+
+    private ChunkHash getHash(String name) {
+        return new ChunkHash(
+                Arrays.copyOf(name.getBytes(Charsets.UTF_8), ChunkHash.HASH_LENGTH_BYTES));
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
new file mode 100644
index 0000000..1cd1528
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import com.google.common.primitives.Bytes;
+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 EncryptedChunkOrderingTest {
+    private static final byte[] TEST_BYTE_ARRAY_1 = new byte[] {1, 2, 3, 4, 5};
+    private static final byte[] TEST_BYTE_ARRAY_2 = new byte[] {5, 4, 3, 2, 1};
+
+    @Test
+    public void testEncryptedChunkOrdering_returnsValue() {
+        EncryptedChunkOrdering encryptedChunkOrdering =
+                EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
+
+        byte[] bytes = encryptedChunkOrdering.encryptedChunkOrdering();
+
+        assertThat(bytes)
+                .asList()
+                .containsExactlyElementsIn(Bytes.asList(TEST_BYTE_ARRAY_1))
+                .inOrder();
+    }
+
+    @Test
+    public void testEquals() {
+        EncryptedChunkOrdering chunkOrdering1 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
+        EncryptedChunkOrdering equalChunkOrdering1 =
+                EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
+        EncryptedChunkOrdering chunkOrdering2 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_2);
+
+        assertThat(chunkOrdering1).isEqualTo(equalChunkOrdering1);
+        assertThat(chunkOrdering1).isNotEqualTo(chunkOrdering2);
+    }
+
+    @Test
+    public void testHashCode() {
+        EncryptedChunkOrdering chunkOrdering1 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
+        EncryptedChunkOrdering equalChunkOrdering1 =
+                EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
+        EncryptedChunkOrdering chunkOrdering2 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_2);
+
+        int hash1 = chunkOrdering1.hashCode();
+        int equalHash1 = equalChunkOrdering1.hashCode();
+        int hash2 = chunkOrdering2.hashCode();
+
+        assertThat(hash1).isEqualTo(equalHash1);
+        assertThat(hash1).isNotEqualTo(hash2);
+    }
+}
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/AgentExceptionTest.java b/services/robotests/src/com/android/server/backup/keyvalue/AgentExceptionTest.java
new file mode 100644
index 0000000..3730335
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/keyvalue/AgentExceptionTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyvalue;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.io.IOException;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class AgentExceptionTest {
+    @Test
+    public void testTransitory_isTransitory() throws Exception {
+        AgentException exception = AgentException.transitory();
+
+        assertThat(exception.isTransitory()).isTrue();
+    }
+
+    @Test
+    public void testTransitory_withCause() throws Exception {
+        Exception cause = new IOException();
+
+        AgentException exception = AgentException.transitory(cause);
+
+        assertThat(exception.isTransitory()).isTrue();
+        assertThat(exception.getCause()).isEqualTo(cause);
+    }
+
+    @Test
+    public void testPermanent_isNotTransitory() throws Exception {
+        AgentException exception = AgentException.permanent();
+
+        assertThat(exception.isTransitory()).isFalse();
+    }
+
+    @Test
+    public void testPermanent_withCause() throws Exception {
+        Exception cause = new IOException();
+
+        AgentException exception = AgentException.permanent(cause);
+
+        assertThat(exception.isTransitory()).isFalse();
+        assertThat(exception.getCause()).isEqualTo(cause);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.java b/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.java
new file mode 100644
index 0000000..5ea74f1
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.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.keyvalue;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.io.IOException;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class BackupExceptionTest {
+    @Test
+    public void testConstructor_passesCause() {
+        Exception cause = new IOException();
+
+        Exception exception = new BackupException(cause);
+
+        assertThat(exception.getCause()).isEqualTo(cause);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java
index 21b90f1..31e8333 100644
--- a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java
+++ b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java
@@ -62,6 +62,13 @@
     }
 
     @Test
+    public void testMoreDebug_isFalse() throws Exception {
+        boolean moreDebug = KeyValueBackupReporter.MORE_DEBUG;
+
+        assertThat(moreDebug).isFalse();
+    }
+
+    @Test
     public void testOnNewThread_logsCorrectly() throws Exception {
         KeyValueBackupReporter.onNewThread("foo");
 
@@ -81,39 +88,4 @@
 
         assertThat(observer).isEqualTo(mObserver);
     }
-
-    @Test
-    public void testOnRevertTask_logsCorrectly() throws Exception {
-        setMoreDebug(true);
-
-        mReporter.onRevertTask();
-
-        assertLogcat(TAG, Log.INFO);
-    }
-
-    @Test
-    public void testOnRemoteCallReturned_logsCorrectly() throws Exception {
-        setMoreDebug(true);
-
-        mReporter.onRemoteCallReturned(RemoteResult.of(3), "onFoo()");
-
-        assertLogcat(TAG, Log.VERBOSE);
-        ShadowLog.LogItem log = ShadowLog.getLogsForTag(TAG).get(0);
-        assertThat(log.msg).contains("onFoo()");
-        assertThat(log.msg).contains("3");
-    }
-
-    /**
-     * HACK: We actually want {@link KeyValueBackupReporter#MORE_DEBUG} to be a constant to be able
-     * to strip those lines at build time. So, we have to do this to test :(
-     */
-    private static void setMoreDebug(boolean value)
-            throws NoSuchFieldException, IllegalAccessException {
-        if (KeyValueBackupReporter.MORE_DEBUG == value) {
-            return;
-        }
-        Field moreDebugField = KeyValueBackupReporter.class.getDeclaredField("MORE_DEBUG");
-        moreDebugField.setAccessible(true);
-        moreDebugField.set(null, value);
-    }
 }
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 b4bc9d1..fb57d68 100644
--- a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -155,9 +155,7 @@
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Stream;
 
-// TODO: When returning to RUNNING_QUEUE vs FINAL, RUNNING_QUEUE sets status = OK. Why? Verify?
-// TODO: Check queue in general, behavior w/ multiple packages
-// TODO: Test PM invocation
+// TODO: Test agents timing out
 @RunWith(FrameworkRobolectricTestRunner.class)
 @Config(
         manifest = Config.NONE,
@@ -370,6 +368,47 @@
     }
 
     @Test
+    public void testRunTask_whenOnePackage_cleansUpPmFiles() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        assertCleansUpFiles(mTransport, PM_PACKAGE);
+    }
+
+    @Test
+    public void testRunTask_whenTransportReturnsTransportErrorForPm_cleansUpPmFiles()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        when(transportMock.transport.performBackup(
+                        argThat(packageInfo(PM_PACKAGE)), any(), anyInt()))
+                .thenReturn(BackupTransport.TRANSPORT_PACKAGE_REJECTED);
+        setUpAgent(PACKAGE_1);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        assertCleansUpFiles(mTransport, PM_PACKAGE);
+    }
+
+    @Test
+    public void testRunTask_whenTransportReturnsTransportErrorForPm_resetsBackupState()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        when(transportMock.transport.performBackup(
+                        argThat(packageInfo(PM_PACKAGE)), any(), anyInt()))
+                .thenReturn(BackupTransport.TRANSPORT_PACKAGE_REJECTED);
+        setUpAgent(PACKAGE_1);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        verify(mBackupManagerService).resetBackupState(getStateDirectory(mTransport).toFile());
+    }
+
+    @Test
     public void testRunTask_whenOnePackage_updatesBookkeeping() throws Exception {
         // Transport has to be initialized to not reset current token
         TransportMock transportMock = setUpInitializedTransport(mTransport);
@@ -418,7 +457,7 @@
     public void testRunTask_whenNonPmPackageAndNonIncremental_doesNotBackUpPm() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         setUpAgentWithData(PACKAGE_1);
-        PackageManagerBackupAgent pmAgent = spy(createPmAgent());
+        BackupAgent pmAgent = spy(createPmAgent());
         when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
         KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1);
 
@@ -431,7 +470,7 @@
     public void testRunTask_whenNonPmPackageAndPmAndNonIncremental_backsUpPm() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         setUpAgentWithData(PACKAGE_1);
-        PackageManagerBackupAgent pmAgent = spy(createPmAgent());
+        BackupAgent pmAgent = spy(createPmAgent());
         when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
         KeyValueBackupTask task =
                 createKeyValueBackupTask(transportMock, true, PACKAGE_1, PM_PACKAGE);
@@ -445,7 +484,7 @@
     public void testRunTask_whenNonPmPackageAndIncremental_backsUpPm() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         setUpAgentWithData(PACKAGE_1);
-        PackageManagerBackupAgent pmAgent = spy(createPmAgent());
+        BackupAgent pmAgent = spy(createPmAgent());
         when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
         KeyValueBackupTask task = createKeyValueBackupTask(transportMock, false, PACKAGE_1);
 
@@ -529,6 +568,35 @@
     }
 
     @Test
+    public void testRunTask_whenPackageUnknown() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        // Not calling setUpAgent() for PACKAGE_1
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        verify(transportMock.transport, never())
+                .performBackup(argThat(packageInfo(PACKAGE_1)), any(), anyInt());
+        verify(mObserver).onResult(PACKAGE_1.packageName, ERROR_PACKAGE_NOT_FOUND);
+        verify(mObserver).backupFinished(SUCCESS);
+        assertBackupNotPendingFor(PACKAGE_1);
+    }
+
+    @Test
+    public void testRunTask_whenFirstPackageUnknown_callsTransportForSecondPackage()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        // Not calling setUpAgent() for PACKAGE_1
+        setUpAgentWithData(PACKAGE_2);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1, PACKAGE_2);
+
+        runTask(task);
+
+        verify(transportMock.transport)
+                .performBackup(argThat(packageInfo(PACKAGE_2)), any(), anyInt());
+    }
+
+    @Test
     public void testRunTask_whenPackageNotEligibleForBackup() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         AgentMock agentMock = setUpAgentWithData(PACKAGE_1.backupNotAllowed());
@@ -545,6 +613,19 @@
     }
 
     @Test
+    public void testRunTask_whenFirstPackageNotEligibleForBackup_callsTransportForSecondPackage()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgentsWithData(PACKAGE_1.backupNotAllowed(), PACKAGE_2);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1, PACKAGE_2);
+
+        runTask(task);
+
+        verify(transportMock.transport)
+                .performBackup(argThat(packageInfo(PACKAGE_2)), any(), anyInt());
+    }
+
+    @Test
     public void testRunTask_whenPackageDoesFullBackup() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         PackageData packageData = fullBackupPackage(1);
@@ -561,6 +642,20 @@
     }
 
     @Test
+    public void testRunTask_whenFirstPackageDoesFullBackup_callsTransportForSecondPackage()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        PackageData packageData = fullBackupPackage(1);
+        setUpAgentsWithData(packageData, PACKAGE_2);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, packageData, PACKAGE_2);
+
+        runTask(task);
+
+        verify(transportMock.transport)
+                .performBackup(argThat(packageInfo(PACKAGE_2)), any(), anyInt());
+    }
+
+    @Test
     public void testRunTask_whenPackageIsStopped() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         AgentMock agentMock = setUpAgentWithData(PACKAGE_1.stopped());
@@ -575,18 +670,16 @@
     }
 
     @Test
-    public void testRunTask_whenPackageUnknown() throws Exception {
+    public void testRunTask_whenFirstPackageIsStopped_callsTransportForSecondPackage()
+            throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
-        // Not calling setUpAgent()
-        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+        setUpAgentsWithData(PACKAGE_1.stopped(), PACKAGE_2);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1, PACKAGE_2);
 
         runTask(task);
 
-        verify(transportMock.transport, never())
-                .performBackup(argThat(packageInfo(PACKAGE_1)), any(), anyInt());
-        verify(mObserver).onResult(PACKAGE_1.packageName, ERROR_PACKAGE_NOT_FOUND);
-        verify(mObserver).backupFinished(SUCCESS);
-        assertBackupNotPendingFor(PACKAGE_1);
+        verify(transportMock.transport)
+                .performBackup(argThat(packageInfo(PACKAGE_2)), any(), anyInt());
     }
 
     @Test
@@ -629,6 +722,7 @@
         verify(mBackupManagerService).setWorkSource(null);
         verify(mObserver).onResult(PACKAGE_1.packageName, ERROR_AGENT_FAILURE);
         verify(mObserver).backupFinished(BackupManager.SUCCESS);
+        assertBackupPendingFor(PACKAGE_1);
     }
 
     @Test
@@ -645,6 +739,7 @@
         verify(mBackupManagerService).setWorkSource(null);
         verify(mObserver).onResult(PACKAGE_1.packageName, ERROR_AGENT_FAILURE);
         verify(mObserver).backupFinished(BackupManager.SUCCESS);
+        assertBackupPendingFor(PACKAGE_1);
     }
 
     @Test
@@ -798,7 +893,7 @@
 
         runTask(task);
 
-        assertBackupNotPendingFor(PACKAGE_1);
+        assertBackupPendingFor(PACKAGE_1);
     }
 
     @Test
@@ -1140,6 +1235,38 @@
     }
 
     @Test
+    public void testRunTask_whenPmAgentWritesData_callsTransportPerformBackupWithAgentData()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        Path backupDataPath = createTemporaryFile();
+        when(transportMock.transport.performBackup(
+                        argThat(packageInfo(PM_PACKAGE)), any(), anyInt()))
+                .then(copyBackupDataTo(backupDataPath));
+        BackupAgent pmAgent = spy(createPmAgent());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
+        agentOnBackupDo(
+                pmAgent,
+                (oldState, dataOutput, newState) -> {
+                    writeData(dataOutput, "key1", "data1".getBytes());
+                    writeData(dataOutput, "key2", "data2".getBytes());
+                    writeState(newState, "newState".getBytes());
+                });
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        verify(transportMock.transport)
+                .performBackup(argThat(packageInfo(PM_PACKAGE)), any(), anyInt());
+        try (FileInputStream inputStream = new FileInputStream(backupDataPath.toFile())) {
+            BackupDataInput backupData = new BackupDataInput(inputStream.getFD());
+            assertDataHasKeyValue(backupData, "key1", "data1".getBytes());
+            assertDataHasKeyValue(backupData, "key2", "data2".getBytes());
+            assertThat(backupData.readNextHeader()).isFalse();
+        }
+    }
+
+    @Test
     public void testRunTask_whenPerformBackupSucceeds_callsTransportFinishBackup()
             throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
@@ -1176,6 +1303,50 @@
     }
 
     @Test
+    public void testRunTask_whenFinishBackupSucceedsForPm_cleansUp() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        when(transportMock.transport.finishBackup()).thenReturn(BackupTransport.TRANSPORT_OK);
+        BackupAgent pmAgent = spy(createPmAgent());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
+        agentOnBackupDo(
+                pmAgent,
+                (oldState, dataOutput, newState) -> {
+                    writeData(dataOutput, "key", "data".getBytes());
+                    writeState(newState, "newState".getBytes());
+                });
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        assertThat(Files.readAllBytes(getStateFile(mTransport, PM_PACKAGE)))
+                .isEqualTo("newState".getBytes());
+        assertCleansUpFiles(mTransport, PM_PACKAGE);
+        // We don't unbind PM
+        verify(mBackupManagerService, never()).unbindAgent(argThat(applicationInfo(PM_PACKAGE)));
+    }
+
+    @Test
+    public void testRunTask_whenFinishBackupSucceedsForPm_doesNotUnbindPm() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        when(transportMock.transport.finishBackup()).thenReturn(BackupTransport.TRANSPORT_OK);
+        BackupAgent pmAgent = spy(createPmAgent());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
+        agentOnBackupDo(
+                pmAgent,
+                (oldState, dataOutput, newState) -> {
+                    writeData(dataOutput, "key", "data".getBytes());
+                    writeState(newState, "newState".getBytes());
+                });
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        verify(mBackupManagerService, never()).unbindAgent(argThat(applicationInfo(PM_PACKAGE)));
+    }
+
+    @Test
     public void testRunTask_whenFinishBackupSucceeds_logsBackupPackageEvent() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         setUpAgentWithData(PACKAGE_1);
@@ -1354,6 +1525,7 @@
     public void testRunTask_whenTransportReturnsQuotaExceeded_updatesBookkeeping()
             throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgentWithData(PACKAGE_1);
         when(transportMock.transport.performBackup(
                         argThat(packageInfo(PACKAGE_1)), any(), anyInt()))
                 .thenReturn(BackupTransport.TRANSPORT_QUOTA_EXCEEDED);
@@ -1701,9 +1873,9 @@
     }
 
     @Test
-    public void testRunTask_whenPmAgentFails() throws Exception {
+    public void testRunTask_whenPmAgentFails_reportsCorrectly() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
-        PackageManagerBackupAgent pmAgent = createThrowingPmAgent(new RuntimeException());
+        BackupAgent pmAgent = createThrowingPmAgent(new RuntimeException());
         when(mBackupManagerService.makeMetadataAgent()).thenReturn(pmAgent);
         KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
 
@@ -1718,6 +1890,75 @@
     }
 
     @Test
+    public void testRunTask_whenPmAgentFails_revertsTask() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        BackupAgent pmAgent = createThrowingPmAgent(new RuntimeException());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(pmAgent);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        assertTaskReverted(transportMock, PACKAGE_1);
+    }
+
+    @Test
+    public void testRunTask_whenPmAgentFails_cleansUpFiles() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        BackupAgent pmAgent = createThrowingPmAgent(new RuntimeException());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(pmAgent);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        assertCleansUpFiles(mTransport, PM_PACKAGE);
+    }
+
+    @Test
+    public void testRunTask_whenPmAgentFails_resetsBackupState() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        BackupAgent pmAgent = createThrowingPmAgent(new RuntimeException());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(pmAgent);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+
+        runTask(task);
+
+        verify(mBackupManagerService).resetBackupState(getStateDirectory(mTransport).toFile());
+    }
+
+    @Test
+    public void testRunTask_whenMarkCancelDuringPmOnBackup_resetsBackupState() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        BackupAgent pmAgent = spy(createPmAgent());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+        agentOnBackupDo(
+                pmAgent, (oldState, dataOutput, newState) -> runInWorkerThread(task::markCancel));
+
+        runTask(task);
+
+        verify(mBackupManagerService).resetBackupState(getStateDirectory(mTransport).toFile());
+    }
+
+    @Test
+    public void testRunTask_whenMarkCancelDuringPmOnBackup_cleansUpFiles() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        BackupAgent pmAgent = spy(createPmAgent());
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(forward(pmAgent));
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+        agentOnBackupDo(
+                pmAgent, (oldState, dataOutput, newState) -> runInWorkerThread(task::markCancel));
+
+        runTask(task);
+
+        assertCleansUpFiles(mTransport, PM_PACKAGE);
+    }
+
+    @Test
     public void testRunTask_whenBackupRunning_doesNotThrow() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         when(mBackupManagerService.isBackupOperationInProgress()).thenReturn(true);
@@ -1736,7 +1977,7 @@
 
         runTask(task);
 
-        verify(mReporter).onReadAgentDataError(eq(PACKAGE_1.packageName), any());
+        verify(mReporter).onAgentDataError(eq(PACKAGE_1.packageName), any());
     }
 
     @Test
@@ -1779,6 +2020,24 @@
     }
 
     @Test
+    public void testRunTask_whenMarkCancelDuringAgentOnBackup_cleansUpFiles() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        AgentMock agentMock = setUpAgent(PACKAGE_1);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+        agentOnBackupDo(
+                agentMock,
+                (oldState, dataOutput, newState) -> {
+                    writeData(dataOutput, "key", "data".getBytes());
+                    writeState(newState, "newState".getBytes());
+                    runInWorkerThread(task::markCancel);
+                });
+
+        runTask(task);
+
+        assertCleansUpFiles(mTransport, PACKAGE_1);
+    }
+
+    @Test
     public void
             testRunTask_whenMarkCancelDuringFirstAgentOnBackup_doesNotCallTransportAfterWaitCancel()
                     throws Exception {
@@ -2293,20 +2552,28 @@
      */
     private static void agentOnBackupDo(AgentMock agentMock, BackupAgentOnBackup function)
             throws Exception {
-        doAnswer(
-                        (BackupAgentOnBackup)
-                                (oldState, dataOutput, newState) -> {
-                                    ByteArrayOutputStream outputStream =
-                                            new ByteArrayOutputStream();
-                                    transferStreamedData(
-                                            new FileInputStream(oldState.getFileDescriptor()),
-                                            outputStream);
-                                    agentMock.oldState = outputStream.toByteArray();
-                                    agentMock.oldStateHistory.add(agentMock.oldState);
-                                    function.onBackup(oldState, dataOutput, newState);
-                                })
-                .when(agentMock.agent)
-                .onBackup(any(), any(), any());
+        agentOnBackupDo(
+                agentMock.agent,
+                (oldState, dataOutput, newState) -> {
+                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+                    transferStreamedData(
+                            new FileInputStream(oldState.getFileDescriptor()), outputStream);
+                    agentMock.oldState = outputStream.toByteArray();
+                    agentMock.oldStateHistory.add(agentMock.oldState);
+                    function.onBackup(oldState, dataOutput, newState);
+                });
+    }
+
+    /**
+     * Implements {@code function} for {@link BackupAgent#onBackup(ParcelFileDescriptor,
+     * BackupDataOutput, ParcelFileDescriptor)} of {@code agentMock}.
+     *
+     * @see #agentOnBackupDo(AgentMock, BackupAgentOnBackup)
+     * @see #remoteAgentOnBackupThrows(AgentMock, BackupAgentOnBackup)
+     */
+    private static void agentOnBackupDo(BackupAgent backupAgent, BackupAgentOnBackup function)
+            throws IOException {
+        doAnswer(function).when(backupAgent).onBackup(any(), any(), any());
     }
 
     /**
@@ -2400,6 +2667,10 @@
             // constructor
             assertJournalDoesNotContain(mBackupManagerService.getJournal(), packageName);
             assertThat(mBackupManagerService.getPendingBackups()).doesNotContainKey(packageName);
+            // Also verifying BMS is never called since for some cases the package wouldn't be
+            // pending for other reasons (for example it's not eligible for backup). Regardless of
+            // these reasons, we shouldn't mark them as pending backup (call dataChangedImpl()).
+            verify(mBackupManagerService, never()).dataChangedImpl(packageName);
         }
     }
 
diff --git a/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java b/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java
new file mode 100644
index 0000000..4b79657
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyvalue;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.expectThrows;
+
+import android.app.backup.BackupTransport;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.io.IOException;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class TaskExceptionTest {
+    @Test
+    public void testStateCompromised() {
+        TaskException exception = TaskException.stateCompromised();
+
+        assertThat(exception.isStateCompromised()).isTrue();
+        assertThat(exception.getStatus()).isEqualTo(BackupTransport.TRANSPORT_ERROR);
+    }
+
+    @Test
+    public void testStateCompromised_whenCauseInstanceOfTaskException() {
+        Exception cause = TaskException.forStatus(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+
+        TaskException exception = TaskException.stateCompromised(cause);
+
+        assertThat(exception.isStateCompromised()).isTrue();
+        assertThat(exception.getStatus()).isEqualTo(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+        assertThat(exception.getCause()).isEqualTo(cause);
+    }
+
+    @Test
+    public void testStateCompromised_whenCauseNotInstanceOfTaskException() {
+        Exception cause = new IOException();
+
+        TaskException exception = TaskException.stateCompromised(cause);
+
+        assertThat(exception.isStateCompromised()).isTrue();
+        assertThat(exception.getStatus()).isEqualTo(BackupTransport.TRANSPORT_ERROR);
+        assertThat(exception.getCause()).isEqualTo(cause);
+    }
+
+    @Test
+    public void testForStatus_whenTransportOk_throws() {
+        expectThrows(
+                IllegalArgumentException.class,
+                () -> TaskException.forStatus(BackupTransport.TRANSPORT_OK));
+    }
+
+    @Test
+    public void testForStatus_whenTransportNotInitialized() {
+        TaskException exception =
+                TaskException.forStatus(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+
+        assertThat(exception.isStateCompromised()).isFalse();
+        assertThat(exception.getStatus()).isEqualTo(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+    }
+
+    @Test
+    public void testCausedBy_whenCauseInstanceOfTaskException_returnsCause() {
+        Exception cause = TaskException.forStatus(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+
+        TaskException exception = TaskException.causedBy(cause);
+
+        assertThat(exception).isEqualTo(cause);
+    }
+
+    @Test
+    public void testCausedBy_whenCauseNotInstanceOfTaskException() {
+        Exception cause = new IOException();
+
+        TaskException exception = TaskException.causedBy(cause);
+
+        assertThat(exception).isNotEqualTo(cause);
+        assertThat(exception.isStateCompromised()).isFalse();
+        assertThat(exception.getStatus()).isEqualTo(BackupTransport.TRANSPORT_ERROR);
+        assertThat(exception.getCause()).isEqualTo(cause);
+    }
+
+    @Test
+    public void testCreate() {
+        TaskException exception = TaskException.create();
+
+        assertThat(exception.isStateCompromised()).isFalse();
+        assertThat(exception.getStatus()).isEqualTo(BackupTransport.TRANSPORT_ERROR);
+    }
+
+    @Test
+    public void testIsStateCompromised_whenStateCompromised_returnsTrue() {
+        TaskException taskException = TaskException.stateCompromised();
+
+        boolean stateCompromised = taskException.isStateCompromised();
+
+        assertThat(stateCompromised).isTrue();
+    }
+
+    @Test
+    public void testIsStateCompromised_whenCreatedWithCreate_returnsFalse() {
+        TaskException taskException = TaskException.create();
+
+        boolean stateCompromised = taskException.isStateCompromised();
+
+        assertThat(stateCompromised).isFalse();
+    }
+
+    @Test
+    public void testGetStatus_whenStatusIsTransportPackageRejected() {
+        TaskException taskException =
+                TaskException.forStatus(BackupTransport.TRANSPORT_PACKAGE_REJECTED);
+
+        int status = taskException.getStatus();
+
+        assertThat(status).isEqualTo(BackupTransport.TRANSPORT_PACKAGE_REJECTED);
+    }
+
+    @Test
+    public void testGetStatus_whenStatusIsTransportNotInitialized() {
+        TaskException taskException =
+                TaskException.forStatus(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+
+        int status = taskException.getStatus();
+
+        assertThat(status).isEqualTo(BackupTransport.TRANSPORT_NOT_INITIALIZED);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/testing/TransportData.java b/services/robotests/src/com/android/server/backup/testing/TransportData.java
index 4c67180..77f5d9a4 100644
--- a/services/robotests/src/com/android/server/backup/testing/TransportData.java
+++ b/services/robotests/src/com/android/server/backup/testing/TransportData.java
@@ -48,9 +48,9 @@
 
     public static TransportData localTransport() {
         return new TransportData(
-                "android/com.android.internal.backup.LocalTransport",
-                "android/com.android.internal.backup.LocalTransportService",
-                "com.android.internal.backup.LocalTransport",
+                "com.android.localtransport/.LocalTransport",
+                "com.android.localtransport/.LocalTransportService",
+                "com.android.localtransport.LocalTransport",
                 null,
                 "Backing up to debug-only private cache",
                 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..95ed00f
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -0,0 +1,1064 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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_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.anyString;
+
+import android.app.ActivityManagerInternal;
+import android.app.AlarmManager;
+import android.app.IActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.hardware.SensorManager;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+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 MockitoSession mMockingSession;
+    @Mock
+    private AlarmManager mAlarmManager;
+    @Mock
+    private DeviceIdleController.Constants mConstants;
+    @Mock
+    private IActivityManager mIActivityManager;
+    @Mock
+    private LocationManager mLocationManager;
+    @Mock
+    private PowerManager mPowerManager;
+    @Mock
+    private PowerManager.WakeLock mWakeLock;
+
+    class InjectorForTest extends DeviceIdleController.Injector {
+
+        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 null;
+        }
+
+        @Override
+        DeviceIdleController.Constants getConstants(DeviceIdleController controller, Handler handler,
+                ContentResolver resolver) {
+            return mConstants;
+        }
+
+        @Override
+        LocationManager getLocationManager() {
+            return mLocationManager;
+        }
+
+        @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(mock(PowerManagerInternal.class))
+                .when(() -> LocalServices.getService(PowerManagerInternal.class));
+        doReturn(mock(NetworkPolicyManagerInternal.class))
+                .when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class));
+        when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
+        doNothing().when(mWakeLock).acquire();
+        mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
+        mAnyMotionDetector = new AnyMotionDetectorForTest();
+        mDeviceIdleController = new DeviceIdleController(getContext(),
+                new InjectorForTest(getContext()));
+        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 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 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_NoLocationManager() {
+        mDeviceIdleController.setLocationManagerForTest(null);
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+        // 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.
+        doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+        // 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() {
+        doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        // TODO: add tests for when there's a wake-from-idle alarm coming soon.
+        doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+        // 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 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);
+    }
+
+    @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);
+    }
+
+    @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);
+    }
+
+    @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);
+    }
+
+    @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() {
+        enterDeepState(STATE_ACTIVE);
+        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);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_SENSING);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_LOCATING);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+    }
+
+    @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);
+    }
+
+    @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_LOCATING:
+                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.
+                doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+            case STATE_INACTIVE:
+                setScreenOn(false);
+                setChargingOn(false);
+                mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+                //fail(stateToString(mDeviceIdleController.getState()));
+                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(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:
+                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(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 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());
+                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());
+                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/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java
new file mode 100644
index 0000000..26e77eb
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java
@@ -0,0 +1,439 @@
+/*
+ * 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 org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.IDeviceAdminService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+
+import org.mockito.ArgumentMatchers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+@SmallTest
+public class PersistentConnectionTest extends AndroidTestCase {
+    private static final String TAG = "PersistentConnectionTest";
+    
+    private static class MyConnection extends PersistentConnection<IDeviceAdminService> {
+        public long uptimeMillis = 12345;
+
+        public ArrayList<Pair<Runnable, Long>> scheduledRunnables = new ArrayList<>();
+
+        public MyConnection(String tag, Context context, Handler handler, int userId,
+                ComponentName componentName, long rebindBackoffSeconds,
+                double rebindBackoffIncrease, long rebindMaxBackoffSeconds,
+                long resetBackoffDelay) {
+            super(tag, context, handler, userId, componentName,
+                    rebindBackoffSeconds, rebindBackoffIncrease, rebindMaxBackoffSeconds,
+                    resetBackoffDelay);
+        }
+
+        @Override
+        protected int getBindFlags() {
+            return Context.BIND_FOREGROUND_SERVICE;
+        }
+
+        @Override
+        protected IDeviceAdminService asInterface(IBinder binder) {
+            return (IDeviceAdminService) binder;
+        }
+
+        @Override
+        long injectUptimeMillis() {
+            return uptimeMillis;
+        }
+
+        @Override
+        void injectPostAtTime(Runnable r, long uptimeMillis) {
+            scheduledRunnables.add(Pair.create(r, uptimeMillis));
+        }
+
+        @Override
+        void injectRemoveCallbacks(Runnable r) {
+            for (int i = scheduledRunnables.size() - 1; i >= 0; i--) {
+                if (scheduledRunnables.get(i).first.equals(r)) {
+                    scheduledRunnables.remove(i);
+                }
+            }
+        }
+
+        void elapse(long milliSeconds) {
+            uptimeMillis += milliSeconds;
+
+            // Fire the scheduled runnables.
+
+            // Note we collect first and then run all, because sometimes a scheduled runnable
+            // calls removeCallbacks.
+            final ArrayList<Runnable> list = new ArrayList<>();
+
+            for (int i = scheduledRunnables.size() - 1; i >= 0; i--) {
+                if (scheduledRunnables.get(i).second <= uptimeMillis) {
+                    list.add(scheduledRunnables.get(i).first);
+                    scheduledRunnables.remove(i);
+                }
+            }
+
+            Collections.reverse(list);
+            for (Runnable r : list) {
+                r.run();
+            }
+        }
+    }
+
+    public void testAll() {
+        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= */ 999);
+
+        assertFalse(conn.isBound());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+        assertNull(conn.getServiceBinder());
+
+        when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(),
+                any(Handler.class), any(UserHandle.class)))
+                .thenReturn(true);
+
+        // Call bind.
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertNull(conn.getServiceBinder());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+        verify(context).bindServiceAsUser(
+                ArgumentMatchers.argThat(intent -> cn.equals(intent.getComponent())),
+                eq(conn.getServiceConnectionForTest()),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(handler), eq(UserHandle.of(userId)));
+
+        // AM responds...
+        conn.getServiceConnectionForTest().onServiceConnected(cn,
+                new IDeviceAdminService.Stub() {});
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isConnected());
+        assertNotNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+
+        // Now connected.
+
+        // Call unbind...
+        conn.unbind();
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        // Caller bind again...
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertNull(conn.getServiceBinder());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+
+        // Now connected again.
+
+        // The service got killed...
+        conn.getServiceConnectionForTest().onServiceDisconnected(cn);
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+        // Connected again...
+        conn.getServiceConnectionForTest().onServiceConnected(cn,
+                new IDeviceAdminService.Stub() {});
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isConnected());
+        assertNotNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+
+        // 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());
+
+        // 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(11000, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
+                        conn.uptimeMillis + 7500)),
+                conn.scheduledRunnables);
+
+        // Later...
+        conn.elapse(7500);
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(11000, conn.getNextBackoffMsForTest());
+
+
+        // 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(11000, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
+                    conn.uptimeMillis + 11000)),
+                conn.scheduledRunnables);
+
+        // Call unbind...
+        conn.unbind();
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        // Call bind again... And now the backoff is reset to 5000.
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertNull(conn.getServiceBinder());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+    }
+
+    public void testReconnectFiresAfterUnbind() {
+        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= */ 999);
+
+        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);
+
+        // Service crashes.
+        conn.getServiceConnectionForTest().onBindingDied(cn);
+
+        assertFalse(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        // Call unbind.
+        conn.unbind();
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+
+        // Now, at this point, it's possible that the scheduled runnable had already been fired
+        // before during the unbind() call, and waiting on mLock.
+        // To simulate it, we just call the runnable here.
+        conn.getBindForBackoffRunnableForTest().run();
+
+        // Should still not be bound.
+        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/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..2957267 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -58,6 +58,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/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..ea90ffd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 com.android.server.am.ActivityStackSupervisor.ON_TOP;
+
+import static org.junit.Assert.assertEquals;
+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.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;
+    }
+}
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 47ce879..c44e492 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -258,7 +258,7 @@
         uidRec.hasInternetPermission = true;
         mAms.mActiveUids.put(uid, uidRec);
 
-        final ProcessRecord appRec = new ProcessRecord(mAms, new ApplicationInfo(), TAG, uid);
+        final ProcessRecord appRec = new ProcessRecord(mAms, new ApplicationInfo(), TAG, uid, null);
         appRec.thread = Mockito.mock(IApplicationThread.class);
         mAms.mLruProcesses.add(appRec);
 
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index f6e5601..ffc7fa2 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -188,17 +188,13 @@
 
     @Test
     public void testCanBeLaunchedOnDisplay() throws Exception {
-        testSupportsLaunchingResizeable(false /*taskPresent*/, true /*taskResizeable*/,
-                true /*activityResizeable*/, true /*expected*/);
+        mService.mSupportsMultiWindow = true;
+        final ActivityRecord activity = new ActivityBuilder(mService).build();
 
-        testSupportsLaunchingResizeable(false /*taskPresent*/, true /*taskResizeable*/,
-                false /*activityResizeable*/, false /*expected*/);
-
-        testSupportsLaunchingResizeable(true /*taskPresent*/, false /*taskResizeable*/,
-                true /*activityResizeable*/, false /*expected*/);
-
-        testSupportsLaunchingResizeable(true /*taskPresent*/, true /*taskResizeable*/,
-                false /*activityResizeable*/, true /*expected*/);
+        // An activity can be launched on default display.
+        assertTrue(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY));
+        // An activity cannot be launched on a non-existent display.
+        assertFalse(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY + 1));
     }
 
     @Test
@@ -229,26 +225,4 @@
         assertNull(mActivity.pendingOptions);
         assertNotNull(activity2.pendingOptions);
     }
-
-    private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable,
-            boolean activityResizeable, boolean expected) {
-        mService.mSupportsMultiWindow = true;
-
-        final TaskRecord task = taskPresent
-                ? new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build() : null;
-
-        if (task != null) {
-            task.setResizeMode(taskResizeable ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE);
-        }
-
-        final ActivityRecord record = new ActivityBuilder(mService).setTask(task).build();
-        record.info.resizeMode = activityResizeable
-                ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE;
-
-        record.canBeLaunchedOnDisplay(DEFAULT_DISPLAY);
-
-
-        verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected),
-                anyInt(), anyInt(), eq(record.info));
-    }
 }
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..81a0934 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -33,10 +33,12 @@
 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.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 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 +234,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();
@@ -402,4 +405,32 @@
         assertEquals(primaryStack.getBounds(), STACK_SIZE);
         assertEquals(task.getBounds(), TASK_SIZE);
     }
+
+    /**
+     * 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..5fcd2aa 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -38,6 +38,7 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 
 import android.content.pm.ActivityInfo;
 import android.os.UserHandle;
@@ -71,8 +72,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();
     }
 
@@ -720,7 +721,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/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
index e1ebbcf..9192d6b 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -83,7 +83,7 @@
         final WindowProcessController wpc = new WindowProcessController(mService,
                 mService.mContext.getApplicationInfo(), "name", 12345,
                 UserHandle.getUserId(12345), mock(Object.class),
-                mock(WindowProcessListener.class));
+                mock(WindowProcessListener.class), null);
         wpc.setThread(mock(IApplicationThread.class));
 
         mController.addPendingActivityLaunch(
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 749403e..bac4a52 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -208,7 +208,7 @@
 
         // 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 : new ProcessRecord(service.mAm, mock(ApplicationInfo.class), null, 0, null);
 
         doReturn(record).when(service.mAm).getRecordForAppLocked(anyObject());
 
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 9d09f5c..2008861 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -168,6 +168,9 @@
         // 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.mWindowManager = prepareMockWindowManager();
         atm.setWindowManager(am.mWindowManager);
@@ -175,10 +178,9 @@
         // 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();
     }
 
@@ -281,7 +283,7 @@
             final WindowProcessController wpc = new WindowProcessController(mService,
                     mService.mContext.getApplicationInfo(), "name", 12345,
                     UserHandle.getUserId(12345), mock(Object.class),
-                    mock(WindowProcessListener.class));
+                    mock(WindowProcessListener.class), null);
             wpc.setThread(mock(IApplicationThread.class));
             activity.setProcess(wpc);
             return activity;
@@ -439,13 +441,14 @@
         }
 
         @Override
+        void updateUsageStats(ActivityRecord component, boolean resumed) {
+        }
+
+        @Override
         final protected ActivityStackSupervisor createStackSupervisor() {
             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.
@@ -497,10 +500,6 @@
         }
 
         @Override
-        void updateUsageStats(ActivityRecord component, boolean resumed) {
-        }
-
-        @Override
         Configuration getGlobalConfiguration() {
             return mContext.getResources().getConfiguration();
         }
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 87d367f..3819e21 100644
--- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -67,7 +67,7 @@
     @UiThreadTest
     public void testCreateWorks() throws Exception {
         AppErrorDialog.Data data = new AppErrorDialog.Data();
-        data.proc = new ProcessRecord(null, mContext.getApplicationInfo(), "name", 12345);
+        data.proc = new ProcessRecord(null, mContext.getApplicationInfo(), "name", 12345, null);
         data.result = new AppErrorResult();
 
         AppErrorDialog dialog = new AppErrorDialog(mContext, mService, data);
diff --git a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
index 06c7437..9a283fe 100644
--- a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
@@ -16,9 +16,13 @@
 
 package com.android.server.am;
 
+import static com.android.server.am.MemoryStatUtil.BYTES_IN_KILOBYTE;
 import static com.android.server.am.MemoryStatUtil.MemoryStat;
+import static com.android.server.am.MemoryStatUtil.PAGE_SIZE;
+import static com.android.server.am.MemoryStatUtil.parseMemoryMaxUsageFromMemCg;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs;
+import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -29,10 +33,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collections;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class MemoryStatUtilTest {
-    private String MEMORY_STAT_CONTENTS = String.join(
+    private static final String MEMORY_STAT_CONTENTS = String.join(
             "\n",
             "cache 96", // keep different from total_cache to catch reading wrong value
             "rss 97", // keep different from total_rss to catch reading wrong value
@@ -67,7 +73,7 @@
             "total_active_file 81920",
             "total_unevictable 0");
 
-    private String PROC_STAT_CONTENTS = String.join(
+    private static final String PROC_STAT_CONTENTS = String.join(
             " ",
             "1040",
             "(system_server)",
@@ -92,7 +98,7 @@
             "0",
             "2206",
             "1257177088",
-            "3", // this is rss in bytes
+            "3", // this is RSS (number of pages)
             "4294967295",
             "2936971264",
             "2936991289",
@@ -122,18 +128,65 @@
             "3198889956",
             "0");
 
+    private static final String PROC_STATUS_CONTENTS = "Name:\tandroid.youtube\n"
+        + "State:\tS (sleeping)\n"
+        + "Tgid:\t12088\n"
+        + "Pid:\t12088\n"
+        + "PPid:\t723\n"
+        + "TracerPid:\t0\n"
+        + "Uid:\t10083\t10083\t10083\t10083\n"
+        + "Gid:\t10083\t10083\t10083\t10083\n"
+        + "Ngid:\t0\n"
+        + "FDSize:\t128\n"
+        + "Groups:\t3003 9997 20083 50083 \n"
+        + "VmPeak:\t 4546844 kB\n"
+        + "VmSize:\t 4542636 kB\n"
+        + "VmLck:\t       0 kB\n"
+        + "VmPin:\t       0 kB\n"
+        + "VmHWM:\t  137668 kB\n" // RSS high watermark
+        + "VmRSS:\t  126776 kB\n"
+        + "RssAnon:\t   37860 kB\n"
+        + "RssFile:\t   88764 kB\n"
+        + "RssShmem:\t     152 kB\n"
+        + "VmData:\t 4125112 kB\n"
+        + "VmStk:\t    8192 kB\n"
+        + "VmExe:\t      24 kB\n"
+        + "VmLib:\t  102432 kB\n"
+        + "VmPTE:\t    1300 kB\n"
+        + "VmPMD:\t      36 kB\n"
+        + "VmSwap:\t       0 kB\n"
+        + "Threads:\t95\n"
+        + "SigQ:\t0/13641\n"
+        + "SigPnd:\t0000000000000000\n"
+        + "ShdPnd:\t0000000000000000\n"
+        + "SigBlk:\t0000000000001204\n"
+        + "SigIgn:\t0000000000000001\n"
+        + "SigCgt:\t00000006400084f8\n"
+        + "CapInh:\t0000000000000000\n"
+        + "CapPrm:\t0000000000000000\n"
+        + "CapEff:\t0000000000000000\n"
+        + "CapBnd:\t0000000000000000\n"
+        + "CapAmb:\t0000000000000000\n"
+        + "Seccomp:\t2\n"
+        + "Cpus_allowed:\tff\n"
+        + "Cpus_allowed_list:\t0-7\n"
+        + "Mems_allowed:\t1\n"
+        + "Mems_allowed_list:\t0\n"
+        + "voluntary_ctxt_switches:\t903\n"
+        + "nonvoluntary_ctxt_switches:\t104\n";
+
     @Test
-    public void testParseMemoryStatFromMemcg_parsesCorrectValues() throws Exception {
+    public void testParseMemoryStatFromMemcg_parsesCorrectValues() {
         MemoryStat stat = parseMemoryStatFromMemcg(MEMORY_STAT_CONTENTS);
-        assertEquals(stat.pgfault, 1);
-        assertEquals(stat.pgmajfault, 2);
-        assertEquals(stat.rssInBytes, 3);
-        assertEquals(stat.cacheInBytes, 4);
-        assertEquals(stat.swapInBytes, 5);
+        assertEquals(1, stat.pgfault);
+        assertEquals(2, stat.pgmajfault);
+        assertEquals(3, stat.rssInBytes);
+        assertEquals(4, stat.cacheInBytes);
+        assertEquals(5, stat.swapInBytes);
     }
 
     @Test
-    public void testParseMemoryStatFromMemcg_emptyMemoryStatContents() throws Exception {
+    public void testParseMemoryStatFromMemcg_emptyMemoryStatContents() {
         MemoryStat stat = parseMemoryStatFromMemcg("");
         assertNull(stat);
 
@@ -142,21 +195,56 @@
     }
 
     @Test
-    public void testParseMemoryStatFromProcfs_parsesCorrectValues() throws Exception {
+    public void testParseMemoryMaxUsageFromMemCg_parsesCorrectValue() {
+        assertEquals(1234, parseMemoryMaxUsageFromMemCg("1234"));
+    }
+
+    @Test
+    public void testParseMemoryMaxUsageFromMemCg_emptyContents() {
+        assertEquals(0, parseMemoryMaxUsageFromMemCg(""));
+
+        assertEquals(0, parseMemoryMaxUsageFromMemCg(null));
+    }
+
+    @Test
+    public void testParseMemoryMaxUsageFromMemCg_incorrectValue() {
+        assertEquals(0, parseMemoryMaxUsageFromMemCg("memory"));
+    }
+
+    @Test
+    public void testParseMemoryStatFromProcfs_parsesCorrectValues() {
         MemoryStat stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS);
         assertEquals(1, stat.pgfault);
         assertEquals(2, stat.pgmajfault);
-        assertEquals(3, stat.rssInBytes);
+        assertEquals(3 * PAGE_SIZE, stat.rssInBytes);
         assertEquals(0, stat.cacheInBytes);
         assertEquals(0, stat.swapInBytes);
     }
 
     @Test
-    public void testParseMemoryStatFromProcfs_emptyContents() throws Exception {
+    public void testParseMemoryStatFromProcfs_emptyContents() {
         MemoryStat stat = parseMemoryStatFromProcfs("");
         assertNull(stat);
 
         stat = parseMemoryStatFromProcfs(null);
         assertNull(stat);
     }
+
+    @Test
+    public void testParseMemoryStatFromProcfs_invalidValue() {
+        String contents = String.join(" ", Collections.nCopies(24, "memory"));
+        assertNull(parseMemoryStatFromProcfs(contents));
+    }
+
+    @Test
+    public void testParseVmHWMFromProcfs_parsesCorrectValue() {
+        assertEquals(137668, parseVmHWMFromProcfs(PROC_STATUS_CONTENTS) / BYTES_IN_KILOBYTE);
+    }
+
+    @Test
+    public void testParseVmHWMFromProcfs_emptyContents() {
+        assertEquals(0, parseVmHWMFromProcfs(""));
+
+        assertEquals(0, parseVmHWMFromProcfs(null));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
deleted file mode 100644
index 54f93a8..0000000
--- a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
+++ /dev/null
@@ -1,354 +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 org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.admin.IDeviceAdminService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Pair;
-
-import org.mockito.ArgumentMatchers;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-
-@SmallTest
-public class PersistentConnectionTest extends AndroidTestCase {
-    private static class MyConnection extends PersistentConnection<IDeviceAdminService> {
-        public long uptimeMillis = 12345;
-
-        public ArrayList<Pair<Runnable, Long>> scheduledRunnables = new ArrayList<>();
-
-        public MyConnection(String tag, Context context, Handler handler, int userId,
-                ComponentName componentName, long rebindBackoffSeconds,
-                double rebindBackoffIncrease, long rebindMaxBackoffSeconds) {
-            super(tag, context, handler, userId, componentName,
-                    rebindBackoffSeconds, rebindBackoffIncrease, rebindMaxBackoffSeconds);
-        }
-
-        @Override
-        protected IDeviceAdminService asInterface(IBinder binder) {
-            return (IDeviceAdminService) binder;
-        }
-
-        @Override
-        long injectUptimeMillis() {
-            return uptimeMillis;
-        }
-
-        @Override
-        void injectPostAtTime(Runnable r, long uptimeMillis) {
-            scheduledRunnables.add(Pair.create(r, uptimeMillis));
-        }
-
-        @Override
-        void injectRemoveCallbacks(Runnable r) {
-            for (int i = scheduledRunnables.size() - 1; i >= 0; i--) {
-                if (scheduledRunnables.get(i).first.equals(r)) {
-                    scheduledRunnables.remove(i);
-                }
-            }
-        }
-
-        void elapse(long milliSeconds) {
-            uptimeMillis += milliSeconds;
-
-            // Fire the scheduled runnables.
-
-            // Note we collect first and then run all, because sometimes a scheduled runnable
-            // calls removeCallbacks.
-            final ArrayList<Runnable> list = new ArrayList<>();
-
-            for (int i = scheduledRunnables.size() - 1; i >= 0; i--) {
-                if (scheduledRunnables.get(i).second <= uptimeMillis) {
-                    list.add(scheduledRunnables.get(i).first);
-                    scheduledRunnables.remove(i);
-                }
-            }
-
-            Collections.reverse(list);
-            for (Runnable r : list) {
-                r.run();
-            }
-        }
-    }
-
-    public void testAll() {
-        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);
-
-        assertFalse(conn.isBound());
-        assertFalse(conn.isConnected());
-        assertFalse(conn.isRebindScheduled());
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-        assertNull(conn.getServiceBinder());
-
-        when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(),
-                any(Handler.class), any(UserHandle.class)))
-                .thenReturn(true);
-
-        // Call bind.
-        conn.bind();
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertFalse(conn.isRebindScheduled());
-        assertNull(conn.getServiceBinder());
-
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-
-        verify(context).bindServiceAsUser(
-                ArgumentMatchers.argThat(intent -> cn.equals(intent.getComponent())),
-                eq(conn.getServiceConnectionForTest()),
-                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
-                eq(handler), eq(UserHandle.of(userId)));
-
-        // AM responds...
-        conn.getServiceConnectionForTest().onServiceConnected(cn,
-                new IDeviceAdminService.Stub() {});
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertTrue(conn.isConnected());
-        assertNotNull(conn.getServiceBinder());
-        assertFalse(conn.isRebindScheduled());
-
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-
-
-        // Now connected.
-
-        // Call unbind...
-        conn.unbind();
-        assertFalse(conn.isBound());
-        assertFalse(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertNull(conn.getServiceBinder());
-        assertFalse(conn.isRebindScheduled());
-
-        // Caller bind again...
-        conn.bind();
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertFalse(conn.isRebindScheduled());
-        assertNull(conn.getServiceBinder());
-
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-
-
-        // Now connected again.
-
-        // The service got killed...
-        conn.getServiceConnectionForTest().onServiceDisconnected(cn);
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertNull(conn.getServiceBinder());
-        assertFalse(conn.isRebindScheduled());
-
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-
-        // Connected again...
-        conn.getServiceConnectionForTest().onServiceConnected(cn,
-                new IDeviceAdminService.Stub() {});
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertTrue(conn.isConnected());
-        assertNotNull(conn.getServiceBinder());
-        assertFalse(conn.isRebindScheduled());
-
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-
-
-        // 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());
-
-        // 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(11000, conn.getNextBackoffMsForTest());
-
-        assertEquals(
-                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
-                        conn.uptimeMillis + 7500)),
-                conn.scheduledRunnables);
-
-        // Later...
-        conn.elapse(7500);
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertNull(conn.getServiceBinder());
-        assertFalse(conn.isRebindScheduled());
-
-        assertEquals(11000, conn.getNextBackoffMsForTest());
-
-
-        // 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(11000, conn.getNextBackoffMsForTest());
-
-        assertEquals(
-                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
-                    conn.uptimeMillis + 11000)),
-                conn.scheduledRunnables);
-
-        // Call unbind...
-        conn.unbind();
-        assertFalse(conn.isBound());
-        assertFalse(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertNull(conn.getServiceBinder());
-        assertFalse(conn.isRebindScheduled());
-
-        // Call bind again... And now the backoff is reset to 5000.
-        conn.bind();
-
-        assertTrue(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertFalse(conn.isConnected());
-        assertFalse(conn.isRebindScheduled());
-        assertNull(conn.getServiceBinder());
-
-        assertEquals(5000, conn.getNextBackoffMsForTest());
-    }
-
-    public void testReconnectFiresAfterUnbind() {
-        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);
-
-        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);
-
-        // Service crashes.
-        conn.getServiceConnectionForTest().onBindingDied(cn);
-
-        assertFalse(conn.isBound());
-        assertTrue(conn.shouldBeBoundForTest());
-        assertTrue(conn.isRebindScheduled());
-
-        assertEquals(7500, conn.getNextBackoffMsForTest());
-
-        // Call unbind.
-        conn.unbind();
-        assertFalse(conn.isBound());
-        assertFalse(conn.shouldBeBoundForTest());
-
-        // Now, at this point, it's possible that the scheduled runnable had already been fired
-        // before during the unbind() call, and waiting on mLock.
-        // To simulate it, we just call the runnable here.
-        conn.getBindForBackoffRunnableForTest().run();
-
-        // Should still not be bound.
-        assertFalse(conn.isBound());
-        assertFalse(conn.shouldBeBoundForTest());
-    }
-}
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..1276f65 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -125,7 +125,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 +557,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 +577,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 +598,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
@@ -870,7 +866,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 +877,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/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/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/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/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/FakeWindowState.java b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
index b238e43..d34f951 100644
--- a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
+++ b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
@@ -30,7 +30,7 @@
 
 public class FakeWindowState implements WindowManagerPolicy.WindowState {
 
-    private WindowFrames windowFrames;
+    private WindowFrames mWindowFrames = new WindowFrames();
 
     public WindowManager.LayoutParams attrs;
     public int displayId;
@@ -53,41 +53,40 @@
     }
 
     @Override
-    public void computeFrameLw(WindowFrames windowFrames) {
-        this.windowFrames = windowFrames;
+    public void computeFrameLw() {
     }
 
     @Override
     public Rect getFrameLw() {
-        return windowFrames.mParentFrame;
+        return mWindowFrames.mParentFrame;
     }
 
     @Override
     public Rect getDisplayFrameLw() {
-        return windowFrames.mDisplayFrame;
+        return mWindowFrames.mDisplayFrame;
     }
 
     @Override
     public Rect getOverscanFrameLw() {
-        return windowFrames.mOverscanFrame;
+        return mWindowFrames.mOverscanFrame;
     }
 
     @Override
     public Rect getContentFrameLw() {
-        return windowFrames.mContentFrame;
+        return mWindowFrames.mContentFrame;
     }
 
     @Override
     public Rect getVisibleFrameLw() {
-        return windowFrames.mVisibleFrame;
+        return mWindowFrames.mVisibleFrame;
     }
 
     public Rect getStableFrame() {
-        return windowFrames.mStableFrame;
+        return mWindowFrames.mStableFrame;
     }
 
     public Rect getDecorFrame() {
-        return windowFrames.mDecorFrame;
+        return mWindowFrames.mDecorFrame;
     }
 
     @Override
@@ -252,6 +251,11 @@
     }
 
     @Override
+    public WindowFrames getWindowFrames() {
+        return mWindowFrames;
+    }
+
+    @Override
     public boolean isInputMethodTarget() {
         return false;
     }
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..bd4a356 100644
--- a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
@@ -84,9 +84,6 @@
     }
 
     @Mock
-    Handler mHandler;
-
-    @Mock
     MetricsLogger mMetricsLogger = mock(MetricsLogger.class);
 
     private BatterySaverPolicyForTest mBatterySaverPolicy;
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 5039e42..8ac2930 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -21,18 +21,32 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManagerInternal;
+import android.content.Context;
+import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.BatteryManagerInternal;
+import android.os.Looper;
 import android.os.PowerManager;
 import android.os.PowerSaveState;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.server.power.batterysaver.BatterySaverController;
+import com.android.internal.app.IBatteryStats;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.lights.LightsManager;
+import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.PowerManagerService.Injector;
+import com.android.server.power.PowerManagerService.NativeWrapper;
+import com.android.server.power.batterysaver.BatterySavingStats;
 
 import org.junit.Rule;
 import org.mockito.Mock;
@@ -47,11 +61,19 @@
     private static final boolean BATTERY_SAVER_ENABLED = true;
     private static final String TEST_LAST_REBOOT_PROPERTY = "test.sys.boot.reason";
 
-    private @Mock BatterySaverPolicy mBatterySaverPolicy;
+    private @Mock BatterySaverPolicy mBatterySaverPolicyMock;
+    private @Mock LightsManager mLightsManagerMock;
+    private @Mock DisplayManagerInternal mDisplayManagerInternalMock;
+    private @Mock BatteryManagerInternal mBatteryManagerInternalMock;
+    private @Mock ActivityManagerInternal mActivityManagerInternalMock;
+    private @Mock PowerManagerService.NativeWrapper mNativeWrapperMock;
+    private @Mock Notifier mNotifierMock;
     private PowerManagerService mService;
     private PowerSaveState mPowerSaveState;
     private DisplayPowerRequest mDisplayPowerRequest;
 
+
+
     @Rule
     public void setUp() throws Exception {
         super.setUp();
@@ -61,11 +83,51 @@
                 .setBatterySaverEnabled(BATTERY_SAVER_ENABLED)
                 .setBrightnessFactor(BRIGHTNESS_FACTOR)
                 .build();
-        when(mBatterySaverPolicy.getBatterySaverPolicy(
+        when(mBatterySaverPolicyMock.getBatterySaverPolicy(
                 eq(PowerManager.ServiceType.SCREEN_BRIGHTNESS), anyBoolean()))
                 .thenReturn(mPowerSaveState);
+
         mDisplayPowerRequest = new DisplayPowerRequest();
-        mService = new PowerManagerService(getContext(), mBatterySaverPolicy);
+        addLocalServiceMock(LightsManager.class, mLightsManagerMock);
+        addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
+        addLocalServiceMock(BatteryManagerInternal.class, mBatteryManagerInternalMock);
+        addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
+
+        mService = new PowerManagerService(getContext(), new Injector() {
+            Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
+                    SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
+                return mNotifierMock;
+            }
+
+            SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
+                return mock(SuspendBlocker.class);
+            }
+
+            BatterySaverPolicy createBatterySaverPolicy(
+                    Object lock, Context context, BatterySavingStats batterySavingStats) {
+                return mBatterySaverPolicyMock;
+            }
+
+            NativeWrapper createNativeWrapper() {
+                return mNativeWrapperMock;
+            }
+        });
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        LocalServices.removeServiceForTest(LightsManager.class);
+        LocalServices.removeServiceForTest(DisplayManagerInternal.class);
+        LocalServices.removeServiceForTest(BatteryManagerInternal.class);
+        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+    }
+
+    /**
+     * Creates a mock and registers it to {@link LocalServices}.
+     */
+    private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
+        LocalServices.removeServiceForTest(clazz);
+        LocalServices.addService(clazz, mock);
     }
 
     @SmallTest
@@ -110,6 +172,25 @@
         mService.setVrModeEnabled(false);
         assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_BRIGHT);
+    }
 
+    @SmallTest
+    public void testWakefulnessAwake_InitialValue() throws Exception {
+        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+    }
+
+    @SmallTest
+    public void testWakefulnessSleep_NoDozeSleepFlag() throws Exception {
+        // Start with AWAKE state
+        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        mService.systemReady(null);
+        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+
+        // Take a nap with a flag.
+        mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
+            PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+
+        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
 }
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/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
new file mode 100644
index 0000000..5a787ec
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS 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.usage;
+
+import static junit.framework.TestCase.assertNull;
+import static junit.framework.TestCase.fail;
+
+import static org.testng.Assert.assertEquals;
+
+import android.app.usage.EventList;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UsageStatsDatabaseTest {
+    protected Context mContext;
+    private UsageStatsDatabase mUsageStatsDatabase;
+    private File mTestDir;
+
+    private IntervalStats mIntervalStats = new IntervalStats();
+    private long mEndTime = 0;
+
+    private static final UsageStatsDatabase.StatCombiner<IntervalStats> mIntervalStatsVerifier =
+            new UsageStatsDatabase.StatCombiner<IntervalStats>() {
+                @Override
+                public void combine(IntervalStats stats, boolean mutable,
+                        List<IntervalStats> accResult) {
+                    accResult.add(stats);
+                }
+            };
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mTestDir = new File(mContext.getFilesDir(), "UsageStatsDatabaseTest");
+        mUsageStatsDatabase = new UsageStatsDatabase(mTestDir);
+        mUsageStatsDatabase.init(1);
+        populateIntervalStats();
+        clearUsageStatsFiles();
+    }
+
+    /**
+     * A debugging utility for viewing the files currently in the test directory
+     */
+    private void clearUsageStatsFiles() {
+        File[] intervalDirs = mTestDir.listFiles();
+        for (File intervalDir : intervalDirs) {
+            if (intervalDir.isDirectory()) {
+                File[] usageFiles = intervalDir.listFiles();
+                for (File f : usageFiles) {
+                    f.delete();
+                }
+            }
+        }
+    }
+
+    /**
+     * A debugging utility for viewing the files currently in the test directory
+     */
+    private String dumpUsageStatsFiles() {
+        StringBuilder sb = new StringBuilder();
+        File[] intervalDirs = mTestDir.listFiles();
+        for (File intervalDir : intervalDirs) {
+            if (intervalDir.isDirectory()) {
+                File[] usageFiles = intervalDir.listFiles();
+                for (File f : usageFiles) {
+                    sb.append(f.toString());
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    private void populateIntervalStats() {
+        final int numberOfEvents = 3000;
+        long time = 1;
+        mIntervalStats = new IntervalStats();
+
+        mIntervalStats.beginTime = 1;
+        mIntervalStats.interactiveTracker.count = 2;
+        mIntervalStats.interactiveTracker.duration = 111111;
+        mIntervalStats.nonInteractiveTracker.count = 3;
+        mIntervalStats.nonInteractiveTracker.duration = 222222;
+        mIntervalStats.keyguardShownTracker.count = 4;
+        mIntervalStats.keyguardShownTracker.duration = 333333;
+        mIntervalStats.keyguardHiddenTracker.count = 5;
+        mIntervalStats.keyguardHiddenTracker.duration = 4444444;
+
+        if (mIntervalStats.events == null) {
+            mIntervalStats.events = new EventList();
+        }
+
+        for (int i = 0; i < numberOfEvents; i++) {
+            UsageEvents.Event event = new UsageEvents.Event();
+            final int packageInt = ((i / 3) % 7);
+            event.mPackage = "fake.package.name" + packageInt; //clusters of 3 events from 7 "apps"
+            if (packageInt == 3) {
+                // Third app is an instant app
+                event.mFlags |= UsageEvents.Event.FLAG_IS_PACKAGE_INSTANT_APP;
+            } else if (packageInt == 2 || packageInt == 4) {
+                event.mClass = ".fake.class.name" + i % 11;
+            }
+
+
+            event.mTimeStamp = time;
+            event.mEventType = i % 19; //"random" event type
+
+            switch (event.mEventType) {
+                case UsageEvents.Event.CONFIGURATION_CHANGE:
+                    //empty config,
+                    event.mConfiguration = new Configuration();
+                    break;
+                case UsageEvents.Event.SHORTCUT_INVOCATION:
+                    //"random" shortcut
+                    event.mShortcutId = "shortcut" + (i % 8);
+                    break;
+                case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
+                    //"random" bucket and reason
+                    event.mBucketAndReason = (((i % 5 + 1) * 10) << 16) & (i % 5 + 1) << 8;
+                    break;
+                case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+                    //"random" channel
+                    event.mNotificationChannelId = "channel" + (i % 5);
+                    break;
+            }
+
+            mIntervalStats.events.insert(event);
+            mIntervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+
+            time += 23; // Arbitrary progression of time
+        }
+        mEndTime = time;
+
+        Configuration config1 = new Configuration();
+        config1.fontScale = 3.3f;
+        config1.mcc = 4;
+        mIntervalStats.getOrCreateConfigurationStats(config1);
+
+        Configuration config2 = new Configuration();
+        config2.mnc = 5;
+        config2.setLocale(new Locale("en", "US"));
+        mIntervalStats.getOrCreateConfigurationStats(config2);
+
+        Configuration config3 = new Configuration();
+        config3.touchscreen = 6;
+        config3.keyboard = 7;
+        mIntervalStats.getOrCreateConfigurationStats(config3);
+
+        Configuration config4 = new Configuration();
+        config4.keyboardHidden = 8;
+        config4.hardKeyboardHidden = 9;
+        mIntervalStats.getOrCreateConfigurationStats(config4);
+
+        Configuration config5 = new Configuration();
+        config5.navigation = 10;
+        config5.navigationHidden = 11;
+        mIntervalStats.getOrCreateConfigurationStats(config5);
+
+        Configuration config6 = new Configuration();
+        config6.orientation = 12;
+        //Ignore screen layout, it's determined by locale
+        mIntervalStats.getOrCreateConfigurationStats(config6);
+
+        Configuration config7 = new Configuration();
+        config7.colorMode = 14;
+        config7.uiMode = 15;
+        mIntervalStats.getOrCreateConfigurationStats(config7);
+
+        Configuration config8 = new Configuration();
+        config8.screenWidthDp = 16;
+        config8.screenHeightDp = 17;
+        mIntervalStats.getOrCreateConfigurationStats(config8);
+
+        Configuration config9 = new Configuration();
+        config9.smallestScreenWidthDp = 18;
+        config9.densityDpi = 19;
+        mIntervalStats.getOrCreateConfigurationStats(config9);
+
+        mIntervalStats.activeConfiguration = config9;
+    }
+
+    void compareUsageStats(UsageStats us1, UsageStats us2) {
+        assertEquals(us1.mPackageName, us2.mPackageName);
+        // mBeginTimeStamp is based on the enclosing IntervalStats, don't bother checking
+        // mEndTimeStamp is based on the enclosing IntervalStats, don't bother checking
+        assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed);
+        assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground);
+        // mLaunchCount not persisted, so skipped
+        assertEquals(us1.mAppLaunchCount, us2.mAppLaunchCount);
+        assertEquals(us1.mLastEvent, us2.mLastEvent);
+        assertEquals(us1.mChooserCounts, us2.mChooserCounts);
+    }
+
+    void compareUsageEvent(UsageEvents.Event e1, UsageEvents.Event e2, int debugId) {
+        assertEquals(e1.mPackage, e2.mPackage, "Usage event " + debugId);
+        assertEquals(e1.mClass, e2.mClass, "Usage event " + debugId);
+        assertEquals(e1.mTimeStamp, e2.mTimeStamp, "Usage event " + debugId);
+        assertEquals(e1.mEventType, e2.mEventType, "Usage event " + debugId);
+        switch (e1.mEventType) {
+            case UsageEvents.Event.CONFIGURATION_CHANGE:
+                assertEquals(e1.mConfiguration, e2.mConfiguration,
+                        "Usage event " + debugId + e2.mConfiguration.toString());
+                break;
+            case UsageEvents.Event.SHORTCUT_INVOCATION:
+                assertEquals(e1.mShortcutId, e2.mShortcutId, "Usage event " + debugId);
+                break;
+            case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
+                assertEquals(e1.mBucketAndReason, e2.mBucketAndReason, "Usage event " + debugId);
+                break;
+            case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+                assertEquals(e1.mNotificationChannelId, e2.mNotificationChannelId,
+                        "Usage event " + debugId);
+                break;
+        }
+        assertEquals(e1.mFlags, e2.mFlags);
+    }
+
+    void compareIntervalStats(IntervalStats stats1, IntervalStats stats2) {
+        assertEquals(stats1.beginTime, stats2.beginTime);
+        assertEquals(stats1.endTime, stats2.endTime);
+        assertEquals(stats1.interactiveTracker.count, stats2.interactiveTracker.count);
+        assertEquals(stats1.interactiveTracker.duration, stats2.interactiveTracker.duration);
+        assertEquals(stats1.nonInteractiveTracker.count, stats2.nonInteractiveTracker.count);
+        assertEquals(stats1.nonInteractiveTracker.duration, stats2.nonInteractiveTracker.duration);
+        assertEquals(stats1.keyguardShownTracker.count, stats2.keyguardShownTracker.count);
+        assertEquals(stats1.keyguardShownTracker.duration, stats2.keyguardShownTracker.duration);
+        assertEquals(stats1.keyguardHiddenTracker.count, stats2.keyguardHiddenTracker.count);
+        assertEquals(stats1.keyguardHiddenTracker.duration, stats2.keyguardHiddenTracker.duration);
+
+        String[] usageKey1 = stats1.packageStats.keySet().toArray(new String[0]);
+        String[] usageKey2 = stats2.packageStats.keySet().toArray(new String[0]);
+        for (int i = 0; i < usageKey1.length; i++) {
+            UsageStats usageStats1 = stats1.packageStats.get(usageKey1[i]);
+            UsageStats usageStats2 = stats2.packageStats.get(usageKey2[i]);
+            compareUsageStats(usageStats1, usageStats2);
+        }
+
+        assertEquals(stats1.configurations.size(), stats2.configurations.size());
+        Configuration[] configSet1 = stats1.configurations.keySet().toArray(new Configuration[0]);
+        for (int i = 0; i < configSet1.length; i++) {
+            if (!stats2.configurations.containsKey(configSet1[i])) {
+                Configuration[] configSet2 = stats2.configurations.keySet().toArray(
+                        new Configuration[0]);
+                String debugInfo = "";
+                for (Configuration c : configSet1) {
+                    debugInfo += c.toString() + "\n";
+                }
+                debugInfo += "\n";
+                for (Configuration c : configSet2) {
+                    debugInfo += c.toString() + "\n";
+                }
+                fail("Config " + configSet1[i].toString()
+                        + " not found in deserialized IntervalStat\n" + debugInfo);
+            }
+        }
+        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);
+        }
+    }
+
+    /**
+     * Runs the Write Read test.
+     * Will write the generated IntervalStat to disk, read it from disk and compare the two
+     */
+    void runWriteReadTest(int interval) throws IOException {
+        mUsageStatsDatabase.putUsageStats(interval, mIntervalStats);
+        List<IntervalStats> stats = mUsageStatsDatabase.queryUsageStats(interval, 0, mEndTime,
+                mIntervalStatsVerifier);
+
+        assertEquals(1, stats.size());
+        compareIntervalStats(mIntervalStats, stats.get(0));
+    }
+
+    /**
+     * Demonstrate that IntervalStats can be serialized and deserialized from disk without loss of
+     * relevant data.
+     */
+    @Test
+    public void testWriteRead() throws IOException {
+        runWriteReadTest(UsageStatsManager.INTERVAL_DAILY);
+        runWriteReadTest(UsageStatsManager.INTERVAL_WEEKLY);
+        runWriteReadTest(UsageStatsManager.INTERVAL_MONTHLY);
+        runWriteReadTest(UsageStatsManager.INTERVAL_YEARLY);
+    }
+
+    /**
+     * Runs the Version Change tests.
+     * Will write the generated IntervalStat to disk in one version format, "upgrade" to another
+     * version and read the automatically upgraded files on disk in the new file format.
+     */
+    void runVersionChangeTest(int oldVersion, int newVersion, int interval) throws IOException {
+        // Write IntervalStats to disk in old version format
+        UsageStatsDatabase prevDB = new UsageStatsDatabase(mTestDir, oldVersion);
+        prevDB.init(1);
+        prevDB.putUsageStats(interval, mIntervalStats);
+
+        // Simulate an upgrade to a new version and read from the disk
+        UsageStatsDatabase newDB = new UsageStatsDatabase(mTestDir, newVersion);
+        newDB.init(mEndTime);
+        List<IntervalStats> stats = newDB.queryUsageStats(interval, 0, mEndTime,
+                mIntervalStatsVerifier);
+
+        assertEquals(1, stats.size());
+        // The written and read IntervalStats should match
+        compareIntervalStats(mIntervalStats, stats.get(0));
+    }
+
+    /**
+     * Test the version upgrade from 3 to 4
+     */
+    @Test
+    public void testVersionUpgradeFrom3to4() throws IOException {
+        runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_DAILY);
+        runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_WEEKLY);
+        runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_MONTHLY);
+        runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_YEARLY);
+    }
+}
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..3dcdd23 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,6 +34,7 @@
 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;
@@ -303,7 +306,8 @@
                 createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
 
         // 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();
@@ -313,7 +317,8 @@
                 createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
 
         // Check focus is on secondary.
-        assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
+        assertEquals(sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
+                dc1.findFocusedWindow());
     }
 
     @Test
@@ -321,34 +326,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 +454,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 +484,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 +501,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 +590,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.
diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index e7c45d5..088e229 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -24,6 +25,8 @@
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
 
 import static org.junit.Assert.fail;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.verify;
@@ -33,9 +36,11 @@
 import android.os.Binder;
 import android.os.IInterface;
 import android.platform.test.annotations.Presubmit;
+import android.util.SparseBooleanArray;
 import android.view.IRecentsAnimationRunner;
 import android.view.SurfaceControl;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -109,6 +114,25 @@
         }
     }
 
+    @Test
+    @FlakyTest(bugId = 117117823)
+    public void testIncludedApps_expectTargetAndVisible() throws Exception {
+        sWm.setRecentsAnimationController(mController);
+        final AppWindowToken homeAppWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
+        final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final AppWindowToken hiddenAppWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        hiddenAppWindow.setHidden(true);
+        mController.initialize(mDisplayContent, ACTIVITY_TYPE_HOME, new SparseBooleanArray());
+
+        // Ensure that we are animating the target activity as well
+        assertTrue(mController.isAnimatingTask(homeAppWindow.getTask()));
+        assertTrue(mController.isAnimatingTask(appWindow.getTask()));
+        assertFalse(mController.isAnimatingTask(hiddenAppWindow.getTask()));
+    }
+
     private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
         verify(binder, atLeast(0)).asBinder();
         verifyNoMoreInteractions(binder);
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 5fb8997..474e5b7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -458,12 +458,6 @@
     }
 
     @Override
-    public void setLastInputMethodWindowLw(WindowState ime,
-            WindowState target) {
-
-    }
-
-    @Override
     public void showRecentApps() {
 
     }
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 e648230..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;
@@ -202,8 +202,8 @@
         // When mFrame extends past cf, the content insets are
         // the difference between mFrame and ContentFrame. Visible
         // and stable frames work the same way.
-        final WindowFrames windowFrames = new WindowFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        w.getWindowFrames().setFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
+        w.computeFrameLw();
         assertFrame(w, 0, 0, 1000, 1000);
         assertContentInset(w, 0, topContentInset, 0, bottomContentInset);
         assertVisibleInset(w, 0, topVisibleInset, 0, bottomVisibleInset);
@@ -217,7 +217,7 @@
         w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT
         w.mRequestedWidth = 100;
         w.mRequestedHeight = 100;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, 100, 100, 200, 200);
         assertContentInset(w, 0, 0, 0, 0);
         // In this case the frames are shrunk to the window frame.
@@ -238,8 +238,8 @@
 
         // Here the window has FILL_PARENT, FILL_PARENT
         // so we expect it to fill the entire available frame.
-        final WindowFrames windowFrames = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, pf);
-        w.computeFrameLw(windowFrames);
+        w.getWindowFrames().setFrames(pf, pf, pf, pf, pf, pf, pf, pf);
+        w.computeFrameLw();
         assertFrame(w, 0, 0, 1000, 1000);
 
         // It can select various widths and heights within the bounds.
@@ -247,14 +247,14 @@
         // and we use mRequestedWidth/mRequestedHeight
         w.mAttrs.width = 300;
         w.mAttrs.height = 300;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         // Explicit width and height without requested width/height
         // gets us nothing.
         assertFrame(w, 0, 0, 0, 0);
 
         w.mRequestedWidth = 300;
         w.mRequestedHeight = 300;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         // With requestedWidth/Height we can freely choose our size within the
         // parent bounds.
         assertFrame(w, 0, 0, 300, 300);
@@ -267,14 +267,14 @@
         w.mRequestedWidth = -1;
         w.mAttrs.width = 100;
         w.mAttrs.height = 100;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, 0, 0, 100, 100);
         w.mAttrs.flags = 0;
 
         // But sizes too large will be clipped to the containing frame
         w.mRequestedWidth = 1200;
         w.mRequestedHeight = 1200;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, 0, 0, 1000, 1000);
 
         // Before they are clipped though windows will be shifted
@@ -282,7 +282,7 @@
         w.mAttrs.y = 300;
         w.mRequestedWidth = 1000;
         w.mRequestedHeight = 1000;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, 0, 0, 1000, 1000);
 
         // If there is room to move around in the parent frame the window will be shifted according
@@ -292,16 +292,16 @@
         w.mRequestedWidth = 300;
         w.mRequestedHeight = 300;
         w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
          assertFrame(w, 700, 0, 1000, 300);
         w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, 700, 700, 1000, 1000);
         // Window specified  x and y are interpreted as offsets in the opposite
         // direction of gravity
         w.mAttrs.x = 100;
         w.mAttrs.y = 100;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, 600, 600, 900, 900);
     }
 
@@ -322,8 +322,9 @@
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
-        final WindowFrames windowFrames = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        final WindowFrames windowFrames = w.getWindowFrames();
+        windowFrames.setFrames(pf, pf, pf, pf, pf, pf, pf, mEmptyRect);
+        w.computeFrameLw();
         // For non fullscreen tasks the containing frame is based off the
         // task bounds not the parent frame.
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -336,7 +337,7 @@
         final int cfBottom = logicalHeight / 2;
         final Rect cf = new Rect(0, 0, cfRight, cfBottom);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
         int contentInsetRight = taskRight - cfRight;
         int contentInsetBottom = taskBottom - cfBottom;
@@ -354,7 +355,7 @@
         final int insetBottom = insetTop + (taskBottom - taskTop);
         task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
         contentInsetRight = insetRight - cfRight;
         contentInsetBottom = insetBottom - cfBottom;
@@ -384,13 +385,14 @@
         // We use a decor content frame with insets to produce cropping.
         Rect dcf = new Rect(cf);
 
-        final WindowFrames windowFrames = new WindowFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        final WindowFrames windowFrames = w.getWindowFrames();
+        windowFrames.setFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
+        w.computeFrameLw();
         assertPolicyCrop(w, 0, cf.top, logicalWidth, cf.bottom);
 
         windowFrames.mDecorFrame.setEmpty();
         // Likewise with no decor frame we would get no crop
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertPolicyCrop(w, 0, 0, logicalWidth, logicalHeight);
 
         // Now we set up a window which doesn't fill the entire decor frame.
@@ -404,7 +406,7 @@
         w.mAttrs.height = logicalHeight / 2;
         w.mRequestedWidth = logicalWidth / 2;
         w.mRequestedHeight = logicalHeight / 2;
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
 
         // Normally the crop is shrunk from the decor frame
         // to the computed window frame.
@@ -437,8 +439,9 @@
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
-        final WindowFrames windowFrames = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        final WindowFrames windowFrames = w.getWindowFrames();
+        windowFrames.setFrames(pf, pf, pf, pf, pf, pf, pf, mEmptyRect);
+        w.computeFrameLw();
         // For non fullscreen tasks the containing frame is based off the
         // task bounds not the parent frame.
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -455,7 +458,7 @@
         pf.set(0, 0, logicalWidth, logicalHeight);
         task.mFullscreenForTest = true;
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
         assertFrame(w, cf.left, cf.top, cf.right, cf.bottom);
         assertContentFrame(w, cf);
         assertContentInset(w, 0, 0, 0, 0);
@@ -471,11 +474,13 @@
         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 = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, pf);
+        final WindowFrames windowFrames = w.getWindowFrames();
+        windowFrames.setFrames(pf, pf, pf, pf, pf, pf, pf, pf);
         windowFrames.setDisplayCutout(cutout);
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
 
         assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetTop(), 50);
         assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetBottom(), 0);
@@ -495,11 +500,13 @@
         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 = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, pf);
+        final WindowFrames windowFrames = w.getWindowFrames();
+        windowFrames.setFrames(pf, pf, pf, pf, pf, pf, pf, pf);
         windowFrames.setDisplayCutout(cutout);
-        w.computeFrameLw(windowFrames);
+        w.computeFrameLw();
 
         assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetTop(), 50);
         assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetBottom(), 0);
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 b43d9a6..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;
@@ -76,7 +77,8 @@
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
-@Presubmit
+// TODO(b/116597907): Re-enable this test in postsubmit after the bug is fixed.
+// @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class WindowStateTests extends WindowTestsBase {
 
@@ -369,36 +371,49 @@
         final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
 
         app.mHasSurface = true;
-        app.mToken.mSurfaceControl = mock(SurfaceControl.class);
+        app.mSurfaceControl = mock(SurfaceControl.class);
         try {
             app.getFrameLw().set(10, 20, 60, 80);
+            app.updateSurfacePosition(t);
 
             app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true);
 
             assertTrue(app.mSeamlesslyRotated);
+
+            // Verify we un-rotate the window state surface.
             Matrix matrix = new Matrix();
             // Un-rotate 90 deg
             matrix.setRotate(270);
             // Translate it back to origin
             matrix.postTranslate(0, mDisplayInfo.logicalWidth);
-            verify(t).setMatrix(eq(app.mToken.mSurfaceControl), eq(matrix), any(float[].class));
+            verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class));
+
+            // Verify we update the position as well.
+            float[] currentSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
+            matrix.mapPoints(currentSurfacePos);
+            verify(t).setPosition(eq(app.mSurfaceControl), eq(currentSurfacePos[0]),
+                    eq(currentSurfacePos[1]));
         } finally {
+            app.mSurfaceControl = null;
             app.mHasSurface = false;
-            app.mToken.mSurfaceControl = null;
         }
     }
 
     @Test
     public void testDisplayCutoutIsCalculatedRelativeToFrame() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        WindowFrames wf = new WindowFrames();
+        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(wf);
+        app.computeFrameLw();
         assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
index bbc6550..01b7c4f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
@@ -59,7 +59,8 @@
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
-@Presubmit
+// TODO(b/116597907): Re-enable this test in postsubmit after the bug is fixed.
+// @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class WindowTracingTest extends WindowTestsBase {
 
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/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/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 95d4a15..659c6e7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -20,6 +20,7 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Matchers.any;
@@ -34,6 +35,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -47,6 +49,9 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.IntArray;
+import android.util.SparseArray;
 import android.util.Xml;
 
 import com.android.internal.util.FastXmlSerializer;
@@ -68,7 +73,9 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 public class ManagedServicesTest extends UiServiceTestCase {
 
@@ -113,7 +120,12 @@
             when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
         }
         when(mUm.getUsers()).thenReturn(users);
-        when(mUserProfiles.getCurrentProfileIds()).thenReturn(new int[] {0, 10, 11, 12});
+        IntArray profileIds = new IntArray();
+        profileIds.add(0);
+        profileIds.add(11);
+        profileIds.add(10);
+        profileIds.add(12);
+        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
 
         mExpectedPrimaryPackages = new ArrayMap<>();
         mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package");
@@ -165,12 +177,12 @@
 
     @Test
     public void testBackupAndRestore_migration_preO() throws Exception {
-        ArrayMap backupPrimaryPackages = new ArrayMap<>();
+        ArrayMap<Integer, String> backupPrimaryPackages = new ArrayMap<>();
         backupPrimaryPackages.put(0, "backup.0:backup:0a");
         backupPrimaryPackages.put(10, "10.backup");
         backupPrimaryPackages.put(11, "eleven");
         backupPrimaryPackages.put(12, "");
-        ArrayMap backupPrimaryComponentNames = new ArrayMap<>();
+        ArrayMap<Integer, String> backupPrimaryComponentNames = new ArrayMap<>();
         backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b");
         backupPrimaryComponentNames.put(10, "again/M1");
         backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana");
@@ -179,11 +191,11 @@
         backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages);
         backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames);
 
-        ArrayMap backupSecondaryComponentNames = new ArrayMap<>();
+        ArrayMap<Integer, String> backupSecondaryComponentNames = new ArrayMap<>();
         backupSecondaryComponentNames.put(0, "secondary.1/component.Name");
         backupSecondaryComponentNames.put(10,
                 "this.is.another.package.backup/with.Component:component.backup/2");
-        ArrayMap backupSecondaryPackages = new ArrayMap<>();
+        ArrayMap<Integer, String> backupSecondaryPackages = new ArrayMap<>();
         backupSecondaryPackages.put(0, "");
         backupSecondaryPackages.put(10,
                 "this.is.another.package.backup:package.backup");
@@ -368,7 +380,7 @@
             serializer.endDocument();
             serializer.flush();
 
-            for (int userId : mUserProfiles.getCurrentProfileIds()) {
+            for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
                 List<String> expected =
                         stringToList(mExpectedPrimary.get(approvalLevel).get(userId));
                 List<String> actual = stringToList(Settings.Secure.getStringForUser(
@@ -633,7 +645,7 @@
     }
 
     @Test
-    public void testGetAllowedComponents() throws Exception {
+    public void testGetAllowedComponentsByUser() throws Exception {
         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
                 APPROVAL_BY_COMPONENT);
         loadXml(service);
@@ -708,6 +720,145 @@
         assertTrue(services.isSameUser(service, 10));
     }
 
+    @Test
+    public void testGetAllowedComponents() throws Exception {
+        ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+        loadXml(service);
+
+        SparseArray<ArraySet<ComponentName>> expected = new SparseArray<>();
+
+        ArraySet<ComponentName> expected10 = new ArraySet<>();
+        expected10.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
+        expected10.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
+        expected10.add(ComponentName.unflattenFromString("component/2"));
+        expected10.add(ComponentName.unflattenFromString("package/component2"));
+        expected.put(10, expected10);
+        ArraySet<ComponentName> expected0 = new ArraySet<>();
+        expected0.add(ComponentName.unflattenFromString("secondary/component.Name"));
+        expected0.add(ComponentName.unflattenFromString("this.is.a.package.name/Ba"));
+        expected0.add(ComponentName.unflattenFromString("another.package/B1"));
+        expected.put(0, expected0);
+        ArraySet<ComponentName> expected12 = new ArraySet<>();
+        expected12.add(ComponentName.unflattenFromString("bananas!/Bananas!"));
+        expected.put(12, expected12);
+        expected.put(11, new ArraySet<>());
+
+        SparseArray<ArraySet<ComponentName>> actual =
+                service.getAllowedComponents(mUserProfiles.getCurrentProfileIds());
+
+        assertContentsInAnyOrder(expected, actual);
+    }
+
+    @Test
+    public void testPopulateComponentsToUnbind_forceRebind() {
+        ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+
+        IInterface iInterface = mock(IInterface.class);
+        when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
+
+        ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
+                iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
+                mock(ServiceConnection.class), 26);
+        ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
+                iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
+                mock(ServiceConnection.class), 26);
+        Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
+        removableBoundServices.add(service0);
+        removableBoundServices.add(service10);
+
+        SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
+        Set<ComponentName> allowed0 = new ArraySet<>();
+        allowed0.add(ComponentName.unflattenFromString("a/a"));
+        allowedComponentsToBind.put(0, allowed0);
+        Set<ComponentName> allowed10 = new ArraySet<>();
+        allowed10.add(ComponentName.unflattenFromString("b/b"));
+        allowedComponentsToBind.put(10, allowed10);
+
+        SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
+
+        service.populateComponentsToUnbind(true, removableBoundServices, allowedComponentsToBind,
+                componentsToUnbind);
+
+        assertEquals(2, componentsToUnbind.size());
+        assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("a/a")));
+        assertTrue(componentsToUnbind.get(10).contains(ComponentName.unflattenFromString("b/b")));
+    }
+
+    @Test
+    public void testPopulateComponentsToUnbind() {
+        ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+
+        IInterface iInterface = mock(IInterface.class);
+        when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
+
+        ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
+                iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
+                mock(ServiceConnection.class), 26);
+        ManagedServices.ManagedServiceInfo service0a = service.new ManagedServiceInfo(
+                iInterface, ComponentName.unflattenFromString("c/c"), 0, false,
+                mock(ServiceConnection.class), 26);
+        ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
+                iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
+                mock(ServiceConnection.class), 26);
+        Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
+        removableBoundServices.add(service0);
+        removableBoundServices.add(service0a);
+        removableBoundServices.add(service10);
+
+        SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
+        Set<ComponentName> allowed0 = new ArraySet<>();
+        allowed0.add(ComponentName.unflattenFromString("a/a"));
+        allowedComponentsToBind.put(0, allowed0);
+        Set<ComponentName> allowed10 = new ArraySet<>();
+        allowed10.add(ComponentName.unflattenFromString("b/b"));
+        allowedComponentsToBind.put(10, allowed10);
+
+        SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
+
+        service.populateComponentsToUnbind(false, removableBoundServices, allowedComponentsToBind,
+                componentsToUnbind);
+
+        assertEquals(1, componentsToUnbind.size());
+        assertEquals(1, componentsToUnbind.get(0).size());
+        assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("c/c")));
+    }
+
+    @Test
+    public void populateComponentsToBind() {
+        ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+
+        SparseArray<ArraySet<ComponentName>> approvedComponentsByUser = new SparseArray<>();
+        ArraySet<ComponentName> allowed0 = new ArraySet<>();
+        allowed0.add(ComponentName.unflattenFromString("a/a"));
+        approvedComponentsByUser.put(0, allowed0);
+        ArraySet<ComponentName> allowed10 = new ArraySet<>();
+        allowed10.add(ComponentName.unflattenFromString("b/b"));
+        allowed10.add(ComponentName.unflattenFromString("c/c"));
+        approvedComponentsByUser.put(10, allowed10);
+        ArraySet<ComponentName> allowed15 = new ArraySet<>();
+        allowed15.add(ComponentName.unflattenFromString("d/d"));
+        approvedComponentsByUser.put(15, allowed15);
+
+        IntArray users = new IntArray();
+        users.add(10);
+        users.add(0);
+
+        SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
+
+        service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser);
+
+        assertEquals(2, componentsToBind.size());
+        assertEquals(1, componentsToBind.get(0).size());
+        assertTrue(componentsToBind.get(0).contains(ComponentName.unflattenFromString("a/a")));
+        assertEquals(2, componentsToBind.get(10).size());
+        assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("b/b")));
+        assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c")));
+    }
+
     private void loadXml(ManagedServices service) throws Exception {
         final StringBuffer xml = new StringBuffer();
         xml.append("<" + service.getConfig().xmlTag + ">\n");
@@ -775,7 +926,8 @@
                 ManagedServices.ENABLED_SERVICES_SEPARATOR)));
     }
 
-    private void assertContentsInAnyOrder(List<?> expected, List<?> actual) {
+    private void assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual) {
+        assertNotNull(actual);
         assertEquals(expected.size(), actual.size());
 
         for (Object o : expected) {
@@ -787,6 +939,21 @@
         }
     }
 
+    private void assertContentsInAnyOrder(SparseArray<ArraySet<ComponentName>> expected,
+            SparseArray<ArraySet<ComponentName>> actual) throws Exception {
+        assertEquals(expected.size(), actual.size());
+
+        for (int i = 0; i < expected.size(); i++) {
+            int key = expected.keyAt(i);
+            assertTrue(actual.indexOfKey(key) >= 0);
+            try {
+                assertContentsInAnyOrder(expected.valueAt(i), actual.get(key));
+            } catch (Throwable t) {
+                throw new Exception("Error validating " + key, t);
+            }
+        }
+    }
+
     private void verifyExpectedBoundEntries(ManagedServices service, boolean primary)
             throws Exception {
         ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel)
@@ -920,7 +1087,7 @@
 
         @Override
         protected boolean checkType(IInterface service) {
-            return false;
+            return true;
         }
 
         @Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index f9a4f78..1de1e4e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -33,6 +33,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
 import android.os.UserManager;
+import android.util.IntArray;
 import android.util.Xml;
 
 import com.android.internal.util.FastXmlSerializer;
@@ -103,7 +104,12 @@
         }
         when(mUm.getUsers()).thenReturn(users);
         when(mUm.getUsers(anyBoolean())).thenReturn(users);
-        when(mUserProfiles.getCurrentProfileIds()).thenReturn(new int[] {0, 10, 11, 12});
+        IntArray profileIds = new IntArray();
+        profileIds.add(0);
+        profileIds.add(11);
+        profileIds.add(10);
+        profileIds.add(12);
+        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
     }
 
     @Test
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 4344285..4e007c2d 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;
@@ -97,6 +100,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.MediaStore;
 import android.provider.Settings.Secure;
 import android.service.notification.Adjustment;
@@ -117,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;
@@ -159,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;
@@ -237,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);
@@ -248,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);
 
@@ -301,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;
@@ -2191,6 +2212,26 @@
     }
 
     @Test
+    public void testDontAutogroupIfCritical() throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW);
+        mService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+                mService.new PostNotificationRunnable(r.getKey());
+        runnable.run();
+
+        r = generateNotificationRecord(mTestNotificationChannel, 1, null, false);
+        r.setCriticality(CriticalNotificationExtractor.CRITICAL);
+        runnable = mService.new PostNotificationRunnable(r.getKey());
+        mService.addEnqueuedNotification(r);
+
+        runnable.run();
+        waitForIdle();
+
+        verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
+    }
+
+    @Test
     public void testNoFakeColorizedPermission() throws Exception {
         when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
         Notification.Builder nb = new Notification.Builder(mContext,
@@ -3382,10 +3423,44 @@
     }
 
     @Test
+    public void testIsCallerInstantApp_primaryUser() throws Exception {
+        ApplicationInfo info = new ApplicationInfo();
+        info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
+
+        assertTrue(mService.isCallerInstantApp("any", 45770, 0));
+
+        info.privateFlags = 0;
+        assertFalse(mService.isCallerInstantApp("any", 575370, 0));
+    }
+
+    @Test
+    public void testIsCallerInstantApp_secondaryUser() throws Exception {
+        ApplicationInfo info = new ApplicationInfo();
+        info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(10))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(null);
+
+        assertTrue(mService.isCallerInstantApp("any", 68638450, 10));
+    }
+
+    @Test
+    public void testResolveNotificationUid_sameApp_nonSystemUser() throws Exception {
+        ApplicationInfo info = new ApplicationInfo();
+        info.uid = Binder.getCallingUid();
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(10))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(null);
+
+        int actualUid = mService.resolveNotificationUid("caller", "caller", info.uid, 10);
+
+        assertEquals(info.uid, actualUid);
+    }
+
+    @Test
     public void testResolveNotificationUid_sameApp() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = Binder.getCallingUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
 
         int actualUid = mService.resolveNotificationUid("caller", "caller", info.uid, 0);
 
@@ -3393,17 +3468,14 @@
     }
 
     @Test
-    public void testResolveNotificationUid_sameAppWrongPkg() throws Exception {
+    public void testResolveNotificationUid_sameAppDiffPackage() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = Binder.getCallingUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
 
-        try {
-            mService.resolveNotificationUid("caller", "other", info.uid, 0);
-            fail("Incorrect pkg didn't throw security exception");
-        } catch (SecurityException e) {
-            // yay
-        }
+        int actualUid = mService.resolveNotificationUid("caller", "callerAlso", info.uid, 0);
+
+        assertEquals(info.uid, actualUid);
     }
 
     @Test
@@ -3496,4 +3568,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/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 750345b..79998a5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -284,8 +284,8 @@
         compareChannels(channel2,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
 
-        List<NotificationChannelGroup> actualGroups =
-                mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, false, true).getList();
+        List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
+                PKG_N_MR1, UID_N_MR1, false, true, false).getList();
         boolean foundNcg = false;
         for (NotificationChannelGroup actual : actualGroups) {
             if (ncg.getId().equals(actual.getId())) {
@@ -354,8 +354,8 @@
         compareChannels(channel3,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
 
-        List<NotificationChannelGroup> actualGroups =
-                mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, false, true).getList();
+        List<NotificationChannelGroup> actualGroups = mHelper.getNotificationChannelGroups(
+                PKG_N_MR1, UID_N_MR1, false, true, false).getList();
         boolean foundNcg = false;
         for (NotificationChannelGroup actual : actualGroups) {
             if (ncg.getId().equals(actual.getId())) {
@@ -1350,8 +1350,8 @@
         mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
                 UID_N_MR1});
 
-        assertEquals(0,
-                mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true).getList().size());
+        assertEquals(0, mHelper.getNotificationChannelGroups(
+                PKG_N_MR1, UID_N_MR1, true, true, false).getList().size());
     }
 
     @Test
@@ -1440,8 +1440,8 @@
                 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
 
-        List<NotificationChannelGroup> actual =
-                mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true).getList();
+        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
+                PKG_N_MR1, UID_N_MR1, true, true, false).getList();
         assertEquals(3, actual.size());
         for (NotificationChannelGroup group : actual) {
             if (group.getId() == null) {
@@ -1473,13 +1473,13 @@
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true).getList();
+        mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
 
         channel1.setImportance(IMPORTANCE_LOW);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
 
-        List<NotificationChannelGroup> actual =
-                mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true).getList();
+        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
+                PKG_N_MR1, UID_N_MR1, true, true, false).getList();
 
         assertEquals(2, actual.size());
         for (NotificationChannelGroup group : actual) {
@@ -1490,6 +1490,32 @@
     }
 
     @Test
+    public void testGetChannelGroups_includeEmptyGroups() {
+        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
+
+        NotificationChannel channel1 =
+                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
+        channel1.setGroup(ncg.getId());
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+
+        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
+                PKG_N_MR1, UID_N_MR1, false, false, true).getList();
+
+        assertEquals(2, actual.size());
+        for (NotificationChannelGroup group : actual) {
+            if (Objects.equals(group.getId(), ncg.getId())) {
+                assertEquals(1, group.getChannels().size());
+            }
+            if (Objects.equals(group.getId(), ncgEmpty.getId())) {
+                assertEquals(0, group.getChannels().size());
+            }
+        }
+    }
+
+    @Test
     public void testCreateChannel_updateName() throws Exception {
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 88c6fcf..b955e56 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -32,6 +32,7 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.IntArray;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -235,18 +236,22 @@
         mSnoozeHelper.snooze(r2, 1000);
         mSnoozeHelper.snooze(r3, 1000);
         mSnoozeHelper.snooze(r4, 1000);
-        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
-                new int[] {UserHandle.USER_SYSTEM});
+        IntArray profileIds = new IntArray();
+        profileIds.add(UserHandle.USER_SYSTEM);
+        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
         assertEquals(3, mSnoozeHelper.getSnoozed().size());
-        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
-                new int[] {UserHandle.USER_CURRENT});
+        profileIds = new IntArray();
+        profileIds.add(UserHandle.USER_CURRENT);
+        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
         assertEquals(1, mSnoozeHelper.getSnoozed().size());
     }
 
     @Test
     public void testGetSnoozedByUser_managedProfiles() throws Exception {
-        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
-                new int[] {UserHandle.USER_SYSTEM, UserHandle.USER_CURRENT});
+        IntArray profileIds = new IntArray();
+        profileIds.add(UserHandle.USER_CURRENT);
+        profileIds.add(UserHandle.USER_SYSTEM);
+        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
         NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
@@ -273,8 +278,9 @@
 
     @Test
     public void repostGroupSummary_repostsSummary() throws Exception {
-        when(mUserProfiles.getCurrentProfileIds()).thenReturn(
-                new int[] {UserHandle.USER_SYSTEM});
+        IntArray profileIds = new IntArray();
+        profileIds.add(UserHandle.USER_SYSTEM);
+        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
         NotificationRecord r = getNotificationRecord(
                 "pkg", 1, "one", UserHandle.SYSTEM, "group1", true);
         NotificationRecord r2 = getNotificationRecord(
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/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 91f4bc8..13f3e5e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -45,6 +45,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
@@ -60,6 +61,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Xml;
 
 import com.android.internal.R;
@@ -74,12 +76,16 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -88,7 +94,7 @@
 
     ConditionProviders mConditionProviders;
     @Mock NotificationManager mNotificationManager;
-    @Mock private Resources mResources;
+    private Resources mResources;
     private TestableLooper mTestableLooper;
     private ZenModeHelper mZenModeHelperSpy;
     private Context mContext;
@@ -101,11 +107,17 @@
         mTestableLooper = TestableLooper.get(this);
         mContext = spy(getContext());
         mContentResolver = mContext.getContentResolver();
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mResources.getString(R.string.zen_mode_default_every_night_name)).thenReturn("night");
-        when(mResources.getString(R.string.zen_mode_default_events_name)).thenReturn("events");
-        when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
 
+        mResources = spy(mContext.getResources());
+        try {
+            when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn(
+                    getDefaultConfigParser());
+        } catch (Exception e) {
+            Log.d("ZenModeHelperTest", "Couldn't mock default zen mode config xml file err=" +
+                    e.toString());
+        }
+
+        when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
         mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
                 AppGlobals.getPackageManager());
         mConditionProviders.addSystemProvider(new CountdownConditionProvider());
@@ -113,6 +125,30 @@
                 mConditionProviders));
     }
 
+    private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
+        String xml = "<zen version=\"8\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOff=\"true\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<automatic ruleId=\"EVENTS_DEFAULT_RULE\" enabled=\"false\" snoozing=\"false\""
+                + " name=\"Event\" zen=\"1\""
+                + " component=\"android/com.android.server.notification.EventConditionProvider\""
+                + " conditionId=\"condition://android/event?userId=-10000&amp;calendar=&amp;"
+                + "reply=1\"/>\n"
+                + "<automatic ruleId=\"EVERY_NIGHT_DEFAULT_RULE\" enabled=\"false\""
+                + " snoozing=\"false\" name=\"Sleeping\" zen=\"1\""
+                + " component=\"android/com.android.server.notification.ScheduleConditionProvider\""
+                + " conditionId=\"condition://android/schedule?days=1.2.3.4.5.6.7 &amp;start=22.0"
+                + "&amp;end=7.0&amp;exitAtAlarm=true\"/>"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        return new XmlResourceParserImpl(parser);
+    }
+
     private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version)
             throws Exception {
         XmlSerializer serializer = new FastXmlSerializer();
@@ -649,8 +685,8 @@
         customRule.id = "customRule";
         customRule.name = "Custom Rule";
         customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        customRule.component = new ComponentName("test", "test");
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
+        customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         automaticRules.put("customRule", customRule);
         mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
 
@@ -662,8 +698,8 @@
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
         mZenModeHelperSpy.readXml(parser, true);
-        assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode());
         assertEquals(original, mZenModeHelperSpy.mConfig);
+        assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode());
     }
 
     @Test
@@ -678,6 +714,7 @@
         customRule.name = "Custom Rule";
         customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
+        customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         enabledAutoRule.put("customRule", customRule);
         mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;
 
@@ -842,6 +879,7 @@
         customRule.name = "Custom Rule";
         customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
+        customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         disabledAutoRule.put("customRule", customRule);
         mZenModeHelperSpy.mConfig.automaticRules = disabledAutoRule;
 
@@ -877,6 +915,7 @@
         customRule.name = "Custom Rule";
         customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
+        customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         automaticRules.put("customRule", customRule);
 
         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
@@ -886,6 +925,7 @@
         defaultScheduleRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
                 defaultScheduleRuleInfo);
+        customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
 
@@ -922,6 +962,7 @@
         customRule.name = "Custom Rule";
         customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
+        customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         automaticRules.put("customRule", customRule);
 
         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
@@ -989,6 +1030,14 @@
         assertEquals(1, mZenModeHelperSpy.mConditions.mSubscriptions.size());
     }
 
+    @Test
+    public void testEmptyDefaultRulesMap() {
+        ZenModeConfig config = new ZenModeConfig();
+        config.automaticRules = new ArrayMap<>();
+        mZenModeHelperSpy.mConfig = config;
+        mZenModeHelperSpy.updateDefaultZenRules(); // shouldn't throw null pointer
+    }
+
     private void setupZenConfig() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         mZenModeHelperSpy.mConfig.allowAlarms = false;
@@ -1015,4 +1064,294 @@
         assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers);
         assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
     }
+
+    /**
+     * Wrapper to use XmlPullParser as XmlResourceParser for Resources.getXml()
+     */
+    final class XmlResourceParserImpl implements XmlResourceParser {
+        private XmlPullParser parser;
+
+        public XmlResourceParserImpl(XmlPullParser parser) {
+            this.parser = parser;
+        }
+
+        public int getEventType() throws XmlPullParserException {
+            return parser.getEventType();
+        }
+
+        @Override
+        public void setFeature(String name, boolean state) throws XmlPullParserException {
+            parser.setFeature(name, state);
+        }
+
+        @Override
+        public boolean getFeature(String name) {
+            return false;
+        }
+
+        @Override
+        public void setProperty(String name, Object value) throws XmlPullParserException {
+            parser.setProperty(name, value);
+        }
+
+        @Override
+        public Object getProperty(String name) {
+            return parser.getProperty(name);
+        }
+
+        @Override
+        public void setInput(Reader in) throws XmlPullParserException {
+            parser.setInput(in);
+        }
+
+        @Override
+        public void setInput(InputStream inputStream, String inputEncoding)
+                throws XmlPullParserException {
+            parser.setInput(inputStream, inputEncoding);
+        }
+
+        @Override
+        public String getInputEncoding() {
+            return parser.getInputEncoding();
+        }
+
+        @Override
+        public void defineEntityReplacementText(String entityName, String replacementText)
+                throws XmlPullParserException {
+            parser.defineEntityReplacementText(entityName, replacementText);
+        }
+
+        @Override
+        public int getNamespaceCount(int depth) throws XmlPullParserException {
+            return parser.getNamespaceCount(depth);
+        }
+
+        @Override
+        public String getNamespacePrefix(int pos) throws XmlPullParserException {
+            return parser.getNamespacePrefix(pos);
+        }
+
+        @Override
+        public String getNamespaceUri(int pos) throws XmlPullParserException {
+            return parser.getNamespaceUri(pos);
+        }
+
+        @Override
+        public String getNamespace(String prefix) {
+            return parser.getNamespace(prefix);
+        }
+
+        @Override
+        public int getDepth() {
+            return parser.getDepth();
+        }
+
+        @Override
+        public String getPositionDescription() {
+            return parser.getPositionDescription();
+        }
+
+        @Override
+        public int getLineNumber() {
+            return parser.getLineNumber();
+        }
+
+        @Override
+        public int getColumnNumber() {
+            return parser.getColumnNumber();
+        }
+
+        @Override
+        public boolean isWhitespace() throws XmlPullParserException {
+            return parser.isWhitespace();
+        }
+
+        @Override
+        public String getText() {
+            return parser.getText();
+        }
+
+        @Override
+        public char[] getTextCharacters(int[] holderForStartAndLength) {
+            return parser.getTextCharacters(holderForStartAndLength);
+        }
+
+        @Override
+        public String getNamespace() {
+            return parser.getNamespace();
+        }
+
+        @Override
+        public String getName() {
+            return parser.getName();
+        }
+
+        @Override
+        public String getPrefix() {
+            return parser.getPrefix();
+        }
+
+        @Override
+        public boolean isEmptyElementTag() throws XmlPullParserException {
+            return false;
+        }
+
+        @Override
+        public int getAttributeCount() {
+            return parser.getAttributeCount();
+        }
+
+        public int next() throws IOException, XmlPullParserException {
+            return parser.next();
+        }
+
+        @Override
+        public int nextToken() throws XmlPullParserException, IOException {
+            return parser.next();
+        }
+
+        @Override
+        public void require(int type, String namespace, String name)
+                throws XmlPullParserException, IOException {
+            parser.require(type, namespace, name);
+        }
+
+        @Override
+        public String nextText() throws XmlPullParserException, IOException {
+            return parser.nextText();
+        }
+
+        @Override
+        public String getAttributeNamespace(int index) {
+            return "";
+        }
+
+        @Override
+        public String getAttributeName(int index) {
+            return parser.getAttributeName(index);
+        }
+
+        @Override
+        public String getAttributePrefix(int index) {
+            return parser.getAttributePrefix(index);
+        }
+
+        @Override
+        public String getAttributeType(int index) {
+            return parser.getAttributeType(index);
+        }
+
+        @Override
+        public boolean isAttributeDefault(int index) {
+            return parser.isAttributeDefault(index);
+        }
+
+        @Override
+        public String getAttributeValue(int index) {
+            return parser.getAttributeValue(index);
+        }
+
+        @Override
+        public String getAttributeValue(String namespace, String name) {
+            return parser.getAttributeValue(namespace, name);
+        }
+
+        @Override
+        public int getAttributeNameResource(int index) {
+            return 0;
+        }
+
+        @Override
+        public int getAttributeListValue(String namespace, String attribute, String[] options,
+                int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public boolean getAttributeBooleanValue(String namespace, String attribute,
+                boolean defaultValue) {
+            return false;
+        }
+
+        @Override
+        public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public int getAttributeUnsignedIntValue(String namespace, String attribute,
+                int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public float getAttributeFloatValue(String namespace, String attribute,
+                float defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public int getAttributeListValue(int index, String[] options, int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
+            return false;
+        }
+
+        @Override
+        public int getAttributeResourceValue(int index, int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public int getAttributeIntValue(int index, int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public int getAttributeUnsignedIntValue(int index, int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public float getAttributeFloatValue(int index, float defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public String getIdAttribute() {
+            return null;
+        }
+
+        @Override
+        public String getClassAttribute() {
+            return null;
+        }
+
+        @Override
+        public int getIdAttributeResourceValue(int defaultValue) {
+            return 0;
+        }
+
+        @Override
+        public int getStyleAttribute() {
+            return 0;
+        }
+
+        @Override
+        public void close() {
+        }
+
+        @Override
+        public int nextTag() throws IOException, XmlPullParserException {
+            return parser.nextTag();
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/policy/DummyPolicyTests.java b/services/tests/wmtests/src/com/android/server/policy/DummyPolicyTests.java
new file mode 100644
index 0000000..03fb123
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/DummyPolicyTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+
+import androidx.test.filters.FlakyTest;
+
+/**
+ * Dummy test for com.android.server.policy.
+ * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests.
+ */
+public class DummyPolicyTests {
+
+    @Presubmit
+    @Test
+    public void preSubmitTest() {}
+
+    @FlakyTest
+    @Presubmit
+    @Test
+    public void flakyPreSubmitTest() {}
+
+    @Test
+    public void postSubmitTest() {}
+
+    @FlakyTest
+    @Test
+    public void flakyPostSubmitTest() {}
+}
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index 4b7e21f..db9972f 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -24,7 +24,9 @@
 import android.content.res.Configuration;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.proto.ProtoInputStream;
 
+import java.io.IOException;
 import java.util.List;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -46,7 +48,7 @@
     // keep hundreds of strings that have the same contents. We will read the string
     // and only keep it if it's not in the cache. The GC will take care of the
     // strings that had identical copies in the cache.
-    private final ArraySet<String> mStringCache = new ArraySet<>();
+    public final ArraySet<String> mStringCache = new ArraySet<>();
 
     public static final class EventTracker {
         public long curStartTime;
@@ -129,6 +131,90 @@
         return event;
     }
 
+    /**
+     * Builds a UsageEvents.Event from a proto, but does not add it internally.
+     * Built here to take advantage of the cached String Refs
+     */
+    UsageEvents.Event buildEvent(ProtoInputStream parser, List<String> stringPool)
+            throws IOException {
+        final UsageEvents.Event event = new UsageEvents.Event();
+        while (true) {
+            switch (parser.nextField()) {
+                case (int) IntervalStatsProto.Event.PACKAGE:
+                    event.mPackage = getCachedStringRef(
+                            parser.readString(IntervalStatsProto.Event.PACKAGE));
+                    break;
+                case (int) IntervalStatsProto.Event.PACKAGE_INDEX:
+                    event.mPackage = getCachedStringRef(stringPool.get(
+                            parser.readInt(IntervalStatsProto.Event.PACKAGE_INDEX) - 1));
+                    break;
+                case (int) IntervalStatsProto.Event.CLASS:
+                    event.mClass = getCachedStringRef(
+                            parser.readString(IntervalStatsProto.Event.CLASS));
+                    break;
+                case (int) IntervalStatsProto.Event.CLASS_INDEX:
+                    event.mClass = getCachedStringRef(stringPool.get(
+                            parser.readInt(IntervalStatsProto.Event.CLASS_INDEX) - 1));
+                    break;
+                case (int) IntervalStatsProto.Event.TIME_MS:
+                    event.mTimeStamp = beginTime + parser.readLong(
+                            IntervalStatsProto.Event.TIME_MS);
+                    break;
+                case (int) IntervalStatsProto.Event.FLAGS:
+                    event.mFlags = parser.readInt(IntervalStatsProto.Event.FLAGS);
+                    break;
+                case (int) IntervalStatsProto.Event.TYPE:
+                    event.mEventType = parser.readInt(IntervalStatsProto.Event.TYPE);
+                    break;
+                case (int) IntervalStatsProto.Event.CONFIG:
+                    event.mConfiguration = new Configuration();
+                    event.mConfiguration.readFromProto(parser, IntervalStatsProto.Event.CONFIG);
+                    break;
+                case (int) IntervalStatsProto.Event.SHORTCUT_ID:
+                    event.mShortcutId = parser.readString(
+                            IntervalStatsProto.Event.SHORTCUT_ID).intern();
+                    break;
+                case (int) IntervalStatsProto.Event.STANDBY_BUCKET:
+                    event.mBucketAndReason = parser.readInt(
+                            IntervalStatsProto.Event.STANDBY_BUCKET);
+                    break;
+                case (int) IntervalStatsProto.Event.NOTIFICATION_CHANNEL:
+                    event.mNotificationChannelId = parser.readString(
+                            IntervalStatsProto.Event.NOTIFICATION_CHANNEL);
+                    break;
+                case (int) IntervalStatsProto.Event.NOTIFICATION_CHANNEL_INDEX:
+                    event.mNotificationChannelId = getCachedStringRef(stringPool.get(
+                            parser.readInt(IntervalStatsProto.Event.NOTIFICATION_CHANNEL_INDEX)
+                                    - 1));
+                    break;
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    // Handle default values for certain events types
+                    switch (event.mEventType) {
+                        case UsageEvents.Event.CONFIGURATION_CHANGE:
+                            if (event.mConfiguration == null) {
+                                event.mConfiguration = new Configuration();
+                            }
+                            break;
+                        case UsageEvents.Event.SHORTCUT_INVOCATION:
+                            if (event.mShortcutId == null) {
+                                event.mShortcutId = "";
+                            }
+                            break;
+                        case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+                            if (event.mNotificationChannelId == null) {
+                                event.mNotificationChannelId = "";
+                            }
+                            break;
+                    }
+                    if (event.mTimeStamp == 0) {
+                        //mTimestamp not set, assume default value 0 plus beginTime
+                        event.mTimeStamp = beginTime;
+                    }
+                    return event;
+            }
+        }
+    }
+
     private boolean isStatefulEvent(int eventType) {
         switch (eventType) {
             case UsageEvents.Event.MOVE_TO_FOREGROUND:
@@ -143,8 +229,6 @@
     /**
      * Returns whether the event type is one caused by user visible
      * interaction. Excludes those that are internally generated.
-     * @param eventType
-     * @return
      */
     private boolean isUserVisibleEvent(int eventType) {
         return eventType != UsageEvents.Event.SYSTEM_INTERACTION
@@ -184,6 +268,25 @@
         endTime = timeStamp;
     }
 
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public void addEvent(UsageEvents.Event event) {
+        if (events == null) {
+            events = new EventList();
+        }
+        // Cache common use strings
+        event.mPackage = getCachedStringRef(event.mPackage);
+        if (event.mClass != null) {
+            event.mClass = getCachedStringRef(event.mClass);
+        }
+        if (event.mEventType == UsageEvents.Event.NOTIFICATION_INTERRUPTION) {
+            event.mNotificationChannelId = getCachedStringRef(event.mNotificationChannelId);
+        }
+        events.insert(event);
+    }
+
     void updateChooserCounts(String packageName, String category, String action) {
         UsageStats usageStats = getOrCreateUsageStats(packageName);
         if (usageStats.mChooserCounts == null) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 5ab5dc2..8946d25 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -17,6 +17,7 @@
 package com.android.server.usage;
 
 import android.app.usage.TimeSparseArray;
+import android.app.usage.UsageEvents;
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
 import android.os.Build;
@@ -25,6 +26,10 @@
 import android.util.Slog;
 import android.util.TimeUtils;
 
+import com.android.internal.annotations.VisibleForTesting;
+
+import libcore.io.IoUtils;
+
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.ByteArrayInputStream;
@@ -32,18 +37,49 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.FilenameFilter;
+import java.io.InputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * Provides an interface to query for UsageStat data from an XML database.
+ * Provides an interface to query for UsageStat data from a Protocol Buffer database.
+ *
+ * Prior to version 4, UsageStatsDatabase used XML to store Usage Stats data to disk.
+ * 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.
+ * 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.
+ * 7) Update the version file with the new version and build fingerprint.
+ * 8) Delete the versioned backup files (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.
  */
 public class UsageStatsDatabase {
-    private static final int CURRENT_VERSION = 3;
+    private static final int DEFAULT_CURRENT_VERSION = 3;
 
     // Current version of the backup schema
     static final int BACKUP_VERSION = 1;
@@ -52,10 +88,16 @@
     // same as UsageStatsBackupHelper.KEY_USAGE_STATS
     static final String KEY_USAGE_STATS = "usage_stats";
 
+    // 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;
 
     private static final String TAG = "UsageStatsDatabase";
-    private static final boolean DEBUG = UsageStatsService.DEBUG;
+    // 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 =
@@ -66,21 +108,40 @@
     private final TimeSparseArray<AtomicFile>[] mSortedStatFiles;
     private final UnixCalendar mCal;
     private final File mVersionFile;
+    // 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 boolean mFirstUpdate;
     private boolean mNewUpdate;
 
-    public UsageStatsDatabase(File dir) {
-        mIntervalDirs = new File[] {
+    /**
+     * UsageStatsDatabase constructor that allows setting the version number.
+     * This should only be used for testing.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public UsageStatsDatabase(File dir, int version) {
+        mIntervalDirs = new File[]{
                 new File(dir, "daily"),
                 new File(dir, "weekly"),
                 new File(dir, "monthly"),
                 new File(dir, "yearly"),
         };
+        mCurrentVersion = version;
         mVersionFile = new File(dir, "version");
+        mUpdateBreadcrumb = new File(dir, "breadcrumb");
         mSortedStatFiles = new TimeSparseArray[mIntervalDirs.length];
         mCal = new UnixCalendar(0);
     }
 
+    public UsageStatsDatabase(File dir) {
+        this(dir, DEFAULT_CURRENT_VERSION);
+    }
+
     /**
      * Initialize any directories required and index what stats are available.
      */
@@ -154,7 +215,7 @@
             try {
                 IntervalStats stats = new IntervalStats();
                 for (int i = start; i < fileCount - 1; i++) {
-                    UsageStatsXml.read(files.valueAt(i), stats);
+                    readLocked(files.valueAt(i), stats);
                     if (!checkinAction.checkin(stats)) {
                         return false;
                     }
@@ -190,7 +251,7 @@
         final FilenameFilter backupFileFilter = new FilenameFilter() {
             @Override
             public boolean accept(File dir, String name) {
-                return !name.endsWith(BAK_SUFFIX);
+                return !name.endsWith(BAK_SUFFIX) && !name.endsWith(VERSIONED_BAK_SUFFIX);
             }
         };
 
@@ -210,7 +271,7 @@
                 for (File f : files) {
                     final AtomicFile af = new AtomicFile(f);
                     try {
-                        mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af);
+                        mSortedStatFiles[i].put(parseBeginTime(af), af);
                     } catch (IOException e) {
                         Slog.e(TAG, "failed to index file: " + f, e);
                     }
@@ -252,14 +313,32 @@
             version = 0;
         }
 
-        if (version != CURRENT_VERSION) {
-            Slog.i(TAG, "Upgrading from version " + version + " to " + CURRENT_VERSION);
-            doUpgradeLocked(version);
+        if (version != mCurrentVersion) {
+            Slog.i(TAG, "Upgrading from version " + version + " to " + mCurrentVersion);
+            if (!mUpdateBreadcrumb.exists()) {
+                doUpgradeLocked(version);
+            } 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 (version != CURRENT_VERSION || mNewUpdate) {
+        if (version != mCurrentVersion || mNewUpdate) {
             try (BufferedWriter writer = new BufferedWriter(new FileWriter(mVersionFile))) {
-                writer.write(Integer.toString(CURRENT_VERSION));
+                writer.write(Integer.toString(mCurrentVersion));
                 writer.write("\n");
                 writer.write(currentFingerprint);
                 writer.write("\n");
@@ -269,6 +348,14 @@
                 throw new RuntimeException(e);
             }
         }
+
+        if (mUpdateBreadcrumb.exists()) {
+            // Files should be up to date with current version. Clear the version update breadcrumb
+            if (!KEEP_VAK_FILES) {
+                removeVersionedBackupFiles();
+            }
+            mUpdateBreadcrumb.delete();
+        }
     }
 
     private String getBuildFingerprint() {
@@ -290,6 +377,119 @@
                     }
                 }
             }
+        } else {
+            // Turn all current usage stats files into versioned backup files
+            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);
+                }
+            };
+
+            for (int i = 0; i < mIntervalDirs.length; i++) {
+                File[] files = mIntervalDirs[i].listFiles(backupFileFilter);
+                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);
+                        if (DEBUG) {
+                            Slog.d(TAG, "Creating versioned (" + Integer.toString(thisVersion)
+                                    + ") backup of " + files[j].toString()
+                                    + " stat files for interval "
+                                    + i + " to " + backupFile.toString());
+                        }
+
+                        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);
+                        } catch (IOException e) {
+                            Slog.e(TAG, "Failed to back up file : " + files[j].toString());
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+            }
+
+            // Leave a breadcrumb behind noting that all the usage stats have been copied to a
+            // versioned backup.
+            BufferedWriter writer = null;
+            try {
+                writer = new BufferedWriter(new FileWriter(mUpdateBreadcrumb));
+                writer.write(Long.toString(token));
+                writer.write("\n");
+                writer.write(Integer.toString(thisVersion));
+                writer.write("\n");
+                writer.flush();
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to write new version upgrade breadcrumb");
+                throw new RuntimeException(e);
+            } finally {
+                IoUtils.closeQuietly(writer);
+            }
+        }
+    }
+
+    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);
+            }
+        };
+
+        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,
+                                "Upgrading " + files[j].toString() + " to version ("
+                                        + Integer.toString(
+                                        mCurrentVersion) + ") for interval " + i);
+                    }
+                    try {
+                        IntervalStats stats = new IntervalStats();
+                        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());
+                    }
+                }
+            }
         }
     }
 
@@ -357,7 +557,7 @@
             try {
                 final AtomicFile f = mSortedStatFiles[intervalType].valueAt(fileCount - 1);
                 IntervalStats stats = new IntervalStats();
-                UsageStatsXml.read(f, stats);
+                readLocked(f, stats);
                 return stats;
             } catch (IOException e) {
                 Slog.e(TAG, "Failed to read usage stats file", e);
@@ -379,8 +579,8 @@
          * which means you should make a copy of the data before adding it to the
          * <code>accumulatedResult</code> list.
          *
-         * @param stats The {@link IntervalStats} object selected.
-         * @param mutable Whether or not the data inside the stats object is mutable.
+         * @param stats             The {@link IntervalStats} object selected.
+         * @param mutable           Whether or not the data inside the stats object is mutable.
          * @param accumulatedResult The list to which to add extracted data.
          */
         void combine(IntervalStats stats, boolean mutable, List<T> accumulatedResult);
@@ -443,7 +643,7 @@
                 }
 
                 try {
-                    UsageStatsXml.read(f, stats);
+                    readLocked(f, stats);
                     if (beginTime < stats.endTime) {
                         combiner.combine(stats, false, results);
                     }
@@ -523,14 +723,9 @@
         File[] files = dir.listFiles();
         if (files != null) {
             for (File f : files) {
-                String path = f.getPath();
-                if (path.endsWith(BAK_SUFFIX)) {
-                    f = new File(path.substring(0, path.length() - BAK_SUFFIX.length()));
-                }
-
                 long beginTime;
                 try {
-                    beginTime = UsageStatsXml.parseBeginTime(f);
+                    beginTime = parseBeginTime(f);
                 } catch (IOException e) {
                     beginTime = 0;
                 }
@@ -542,18 +737,13 @@
         }
     }
 
-    private static void pruneChooserCountsOlderThan(File dir, long expiryTime) {
+    private void pruneChooserCountsOlderThan(File dir, long expiryTime) {
         File[] files = dir.listFiles();
         if (files != null) {
             for (File f : files) {
-                String path = f.getPath();
-                if (path.endsWith(BAK_SUFFIX)) {
-                    f = new File(path.substring(0, path.length() - BAK_SUFFIX.length()));
-                }
-
                 long beginTime;
                 try {
-                    beginTime = UsageStatsXml.parseBeginTime(f);
+                    beginTime = parseBeginTime(f);
                 } catch (IOException e) {
                     beginTime = 0;
                 }
@@ -562,7 +752,7 @@
                     try {
                         final AtomicFile af = new AtomicFile(f);
                         final IntervalStats stats = new IntervalStats();
-                        UsageStatsXml.read(af, stats);
+                        readLocked(af, stats);
                         final int pkgCount = stats.packageStats.size();
                         for (int i = 0; i < pkgCount; i++) {
                             UsageStats pkgStats = stats.packageStats.valueAt(i);
@@ -570,7 +760,7 @@
                                 pkgStats.mChooserCounts.clear();
                             }
                         }
-                        UsageStatsXml.write(af, stats);
+                        writeLocked(af, stats);
                     } catch (IOException e) {
                         Slog.e(TAG, "Failed to delete chooser counts from usage stats file", e);
                     }
@@ -579,6 +769,225 @@
         }
     }
 
+
+    private static long parseBeginTime(AtomicFile file) throws IOException {
+        return parseBeginTime(file.getBaseFile());
+    }
+
+    private static long parseBeginTime(File file) throws IOException {
+        String name = file.getName();
+
+        // Parse out the digits from the the front of the file name
+        for (int i = 0; i < name.length(); i++) {
+            final char c = name.charAt(i);
+            if (c < '0' || c > '9') {
+                // found first char that is not a digit.
+                name = name.substring(0, i);
+                break;
+            }
+        }
+
+        try {
+            return Long.parseLong(name);
+        } catch (NumberFormatException e) {
+            throw new IOException(e);
+        }
+    }
+
+    private void writeLocked(AtomicFile file, IntervalStats stats) throws IOException {
+        writeLocked(file, stats, mCurrentVersion);
+    }
+
+    private static void writeLocked(AtomicFile file, IntervalStats stats, int version)
+            throws IOException {
+        FileOutputStream fos = file.startWrite();
+        try {
+            writeLocked(fos, stats, version);
+            file.finishWrite(fos);
+            fos = null;
+        } finally {
+            // When fos is null (successful write), this will no-op
+            file.failWrite(fos);
+        }
+    }
+
+    private void writeLocked(OutputStream out, IntervalStats stats) throws IOException {
+        writeLocked(out, stats, mCurrentVersion);
+    }
+
+    private static void writeLocked(OutputStream out, IntervalStats stats, int version)
+            throws IOException {
+        switch (version) {
+            case 1:
+            case 2:
+            case 3:
+                UsageStatsXml.write(out, stats);
+                break;
+            case 4:
+                UsageStatsProto.write(out, stats);
+                break;
+            default:
+                throw new RuntimeException(
+                        "Unhandled UsageStatsDatabase version: " + Integer.toString(version)
+                                + " on write.");
+        }
+    }
+
+    private void readLocked(AtomicFile file, IntervalStats statsOut) throws IOException {
+        readLocked(file, statsOut, mCurrentVersion);
+    }
+
+    private static void readLocked(AtomicFile file, IntervalStats statsOut, int version)
+            throws IOException {
+        try {
+            FileInputStream in = file.openRead();
+            try {
+                statsOut.beginTime = parseBeginTime(file);
+                readLocked(in, statsOut, version);
+                statsOut.lastTimeSaved = file.getLastModifiedTime();
+            } finally {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    // Empty
+                }
+            }
+        } catch (FileNotFoundException e) {
+            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.
+        // The goal of this check is to make sure the the ProtoInputStream is properly reading from
+        // the UsageStats files.
+        final StringBuilder sb = new StringBuilder();
+        final int failureLogLimit = 10;
+        int failures = 0;
+
+        final int packagesSize = statsOut.packageStats.size();
+        for (int i = 0; i < packagesSize; i++) {
+            final UsageStats stat = statsOut.packageStats.valueAt(i);
+            if (stat == null) {
+                // ArrayMap may contain null values, skip them
+                continue;
+            }
+            if (stat.mPackageName.isEmpty()) {
+                if (failures++ < failureLogLimit) {
+                    sb.append("\nUnexpected empty usage stats package name loaded");
+                }
+            }
+            if (stat.mBeginTimeStamp > statsOut.endTime) {
+                if (failures++ < failureLogLimit) {
+                    sb.append("\nUnreasonable usage stats stat begin timestamp ");
+                    sb.append(stat.mBeginTimeStamp);
+                    sb.append(" loaded (beginTime : ");
+                    sb.append(statsOut.beginTime);
+                    sb.append(", endTime : ");
+                    sb.append(statsOut.endTime);
+                    sb.append(")");
+                }
+            }
+            if (stat.mEndTimeStamp > statsOut.endTime) {
+                if (failures++ < failureLogLimit) {
+                    sb.append("\nUnreasonable usage stats stat end timestamp ");
+                    sb.append(stat.mEndTimeStamp);
+                    sb.append(" loaded (beginTime : ");
+                    sb.append(statsOut.beginTime);
+                    sb.append(", endTime : ");
+                    sb.append(statsOut.endTime);
+                    sb.append(")");
+                }
+            }
+            if (stat.mLastTimeUsed > statsOut.endTime) {
+                if (failures++ < failureLogLimit) {
+                    sb.append("\nUnreasonable usage stats stat last used timestamp ");
+                    sb.append(stat.mLastTimeUsed);
+                    sb.append(" loaded (beginTime : ");
+                    sb.append(statsOut.beginTime);
+                    sb.append(", endTime : ");
+                    sb.append(statsOut.endTime);
+                    sb.append(")");
+                }
+            }
+        }
+
+        if (statsOut.events != null) {
+            final int eventSize = statsOut.events.size();
+            for (int i = 0; i < eventSize; i++) {
+                final UsageEvents.Event event = statsOut.events.get(i);
+                if (event.mPackage.isEmpty()) {
+                    if (failures++ < failureLogLimit) {
+                        sb.append("\nUnexpected empty empty package name loaded");
+                    }
+                }
+                if (event.mTimeStamp < statsOut.beginTime || event.mTimeStamp > statsOut.endTime) {
+                    if (failures++ < failureLogLimit) {
+                        sb.append("\nUnexpected event timestamp ");
+                        sb.append(event.mTimeStamp);
+                        sb.append(" loaded (beginTime : ");
+                        sb.append(statsOut.beginTime);
+                        sb.append(", endTime : ");
+                        sb.append(statsOut.endTime);
+                        sb.append(")");
+                    }
+                }
+                if (event.mEventType < 0 || event.mEventType > UsageEvents.Event.MAX_EVENT_TYPE) {
+                    if (failures++ < failureLogLimit) {
+                        sb.append("\nUnexpected event type ");
+                        sb.append(event.mEventType);
+                        sb.append(" loaded");
+                    }
+                }
+                if ((event.mFlags & ~UsageEvents.Event.VALID_FLAG_BITS) != 0) {
+                    if (failures++ < failureLogLimit) {
+                        sb.append("\nUnexpected event flag bit 0b");
+                        sb.append(Integer.toBinaryString(event.mFlags));
+                        sb.append(" loaded");
+                    }
+                }
+            }
+        }
+
+        if (failures != 0) {
+            if (failures > failureLogLimit) {
+                sb.append("\nFailure log limited (");
+                sb.append(failures);
+                sb.append(" total failures found!)");
+            }
+            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());
+        }
+    }
+
+    private void readLocked(InputStream in, IntervalStats statsOut) throws IOException {
+        readLocked(in, statsOut, mCurrentVersion);
+    }
+
+    private static void readLocked(InputStream in, IntervalStats statsOut, int version)
+            throws IOException {
+        switch (version) {
+            case 1:
+            case 2:
+            case 3:
+                UsageStatsXml.read(in, statsOut);
+                break;
+            case 4:
+                UsageStatsProto.read(in, statsOut);
+                break;
+            default:
+                throw new RuntimeException(
+                        "Unhandled UsageStatsDatabase version: " + Integer.toString(version)
+                                + " on read.");
+        }
+
+    }
+
     /**
      * Update the stats in the database. They may not be written to disk immediately.
      */
@@ -596,7 +1005,7 @@
                 mSortedStatFiles[intervalType].put(stats.beginTime, f);
             }
 
-            UsageStatsXml.write(f, stats);
+            writeLocked(f, stats);
             stats.lastTimeSaved = f.getLastModifiedTime();
         }
     }
@@ -730,7 +1139,7 @@
             throws IOException {
         IntervalStats stats = new IntervalStats();
         try {
-            UsageStatsXml.read(statsFile, stats);
+            readLocked(statsFile, stats);
         } catch (IOException e) {
             Slog.e(TAG, "Failed to read usage stats file", e);
             out.writeInt(0);
@@ -756,12 +1165,12 @@
         if (stats.events != null) stats.events.clear();
     }
 
-    private static byte[] serializeIntervalStats(IntervalStats stats) {
+    private byte[] serializeIntervalStats(IntervalStats stats) {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream out = new DataOutputStream(baos);
         try {
             out.writeLong(stats.beginTime);
-            UsageStatsXml.write(out, stats);
+            writeLocked(out, stats);
         } catch (IOException ioe) {
             Slog.d(TAG, "Serializing IntervalStats Failed", ioe);
             baos.reset();
@@ -769,13 +1178,13 @@
         return baos.toByteArray();
     }
 
-    private static IntervalStats deserializeIntervalStats(byte[] data) {
+    private IntervalStats deserializeIntervalStats(byte[] data) {
         ByteArrayInputStream bais = new ByteArrayInputStream(data);
         DataInputStream in = new DataInputStream(bais);
         IntervalStats stats = new IntervalStats();
         try {
             stats.beginTime = in.readLong();
-            UsageStatsXml.read(in, stats);
+            readLocked(in, stats);
         } catch (IOException ioe) {
             Slog.d(TAG, "DeSerializing IntervalStats Failed", ioe);
             stats = null;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProto.java b/services/usage/java/com/android/server/usage/UsageStatsProto.java
new file mode 100644
index 0000000..30d303f
--- /dev/null
+++ b/services/usage/java/com/android/server/usage/UsageStatsProto.java
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.usage;
+
+import android.app.usage.ConfigurationStats;
+import android.app.usage.EventList;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStats;
+import android.content.res.Configuration;
+import android.util.ArrayMap;
+
+import android.util.Slog;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * UsageStats reader/writer for Protocol Buffer format
+ */
+final class UsageStatsProto {
+    private static String TAG = "UsageStatsProto";
+
+    // Static-only utility class.
+    private UsageStatsProto() {}
+
+    private static List<String> readStringPool(ProtoInputStream proto) throws IOException {
+
+        final long token = proto.start(IntervalStatsProto.STRINGPOOL);
+        List<String> stringPool;
+        if (proto.isNextField(IntervalStatsProto.StringPool.SIZE)) {
+            stringPool = new ArrayList(proto.readInt(IntervalStatsProto.StringPool.SIZE));
+        } else {
+            stringPool = new ArrayList();
+        }
+        while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (proto.getFieldNumber()) {
+                case (int) IntervalStatsProto.StringPool.STRINGS:
+                    stringPool.add(proto.readString(IntervalStatsProto.StringPool.STRINGS));
+                    break;
+            }
+        }
+        proto.end(token);
+        return stringPool;
+    }
+
+    private static void loadUsageStats(ProtoInputStream proto, long fieldId,
+            IntervalStats statsOut, List<String> stringPool)
+            throws IOException {
+
+        final long token = proto.start(fieldId);
+        UsageStats stats;
+        if (proto.isNextField(IntervalStatsProto.UsageStats.PACKAGE_INDEX)) {
+            // Fast path reading the package name index. Most cases this should work since it is
+            // written first
+            stats = statsOut.getOrCreateUsageStats(
+                    stringPool.get(proto.readInt(IntervalStatsProto.UsageStats.PACKAGE_INDEX) - 1));
+        } else if (proto.isNextField(IntervalStatsProto.UsageStats.PACKAGE)) {
+            // No package index, try package name instead
+            stats = statsOut.getOrCreateUsageStats(
+                    proto.readString(IntervalStatsProto.UsageStats.PACKAGE));
+        } else {
+            // Temporarily store collected data to a UsageStats object. This is not efficient.
+            stats = new UsageStats();
+        }
+
+        while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (proto.getFieldNumber()) {
+                case (int) IntervalStatsProto.UsageStats.PACKAGE:
+                    // Fast track failed from some reason, add UsageStats object to statsOut now
+                    UsageStats tempPackage = statsOut.getOrCreateUsageStats(
+                            proto.readString(IntervalStatsProto.UsageStats.PACKAGE));
+                    tempPackage.mLastTimeUsed = stats.mLastTimeUsed;
+                    tempPackage.mTotalTimeInForeground = stats.mTotalTimeInForeground;
+                    tempPackage.mLastEvent = stats.mLastEvent;
+                    tempPackage.mAppLaunchCount = stats.mAppLaunchCount;
+                    stats = tempPackage;
+                    break;
+                case (int) IntervalStatsProto.UsageStats.PACKAGE_INDEX:
+                    // Fast track failed from some reason, add UsageStats object to statsOut now
+                    UsageStats tempPackageIndex = statsOut.getOrCreateUsageStats(stringPool.get(
+                            proto.readInt(IntervalStatsProto.UsageStats.PACKAGE_INDEX) - 1));
+                    tempPackageIndex.mLastTimeUsed = stats.mLastTimeUsed;
+                    tempPackageIndex.mTotalTimeInForeground = stats.mTotalTimeInForeground;
+                    tempPackageIndex.mLastEvent = stats.mLastEvent;
+                    tempPackageIndex.mAppLaunchCount = stats.mAppLaunchCount;
+                    stats = tempPackageIndex;
+                    break;
+                case (int) IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS:
+                    stats.mLastTimeUsed = statsOut.beginTime + proto.readLong(
+                            IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS);
+                    break;
+                case (int) IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS:
+                    stats.mTotalTimeInForeground = proto.readLong(
+                            IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS);
+                    break;
+                case (int) IntervalStatsProto.UsageStats.LAST_EVENT:
+                    stats.mLastEvent = proto.readInt(IntervalStatsProto.UsageStats.LAST_EVENT);
+                    break;
+                case (int) IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT:
+                    stats.mAppLaunchCount = proto.readInt(
+                            IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT);
+                    break;
+                case (int) IntervalStatsProto.UsageStats.CHOOSER_ACTIONS:
+                    final long chooserToken = proto.start(
+                            IntervalStatsProto.UsageStats.CHOOSER_ACTIONS);
+                    loadChooserCounts(proto, stats);
+                    proto.end(chooserToken);
+                    break;
+            }
+        }
+        if (stats.mLastTimeUsed == 0) {
+            // mLastTimeUsed was not assigned, assume default value of 0 plus beginTime;
+            stats.mLastTimeUsed = statsOut.beginTime;
+        }
+        proto.end(token);
+    }
+
+    private static void loadCountAndTime(ProtoInputStream proto, long fieldId,
+            IntervalStats.EventTracker tracker) throws IOException {
+        final long token = proto.start(fieldId);
+        while (true) {
+            switch (proto.nextField()) {
+                case (int) IntervalStatsProto.CountAndTime.COUNT:
+                    tracker.count = proto.readInt(IntervalStatsProto.CountAndTime.COUNT);
+                    break;
+                case (int) IntervalStatsProto.CountAndTime.TIME_MS:
+                    tracker.duration = proto.readLong(IntervalStatsProto.CountAndTime.TIME_MS);
+                    break;
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    proto.end(token);
+                    return;
+            }
+        }
+    }
+
+    private static void loadChooserCounts(ProtoInputStream proto, UsageStats usageStats)
+            throws IOException {
+        if (usageStats.mChooserCounts == null) {
+            usageStats.mChooserCounts = new ArrayMap<>();
+        }
+        String action = null;
+        ArrayMap<String, Integer> counts;
+        if (proto.isNextField(IntervalStatsProto.UsageStats.ChooserAction.NAME)) {
+            // Fast path reading the action name. Most cases this should work since it is written
+            // first
+            action = proto.readString(IntervalStatsProto.UsageStats.ChooserAction.NAME);
+            counts = usageStats.mChooserCounts.get(action);
+            if (counts == null) {
+                counts = new ArrayMap<>();
+                usageStats.mChooserCounts.put(action, counts);
+            }
+        } else {
+            // Temporarily store collected data to an ArrayMap. This is not efficient.
+            counts = new ArrayMap<>();
+        }
+
+        while (true) {
+            switch (proto.nextField()) {
+                case (int) IntervalStatsProto.UsageStats.ChooserAction.NAME:
+                    // Fast path failed from some reason, add the ArrayMap object to usageStats now
+                    action = proto.readString(IntervalStatsProto.UsageStats.ChooserAction.NAME);
+                    usageStats.mChooserCounts.put(action, counts);
+                    break;
+                case (int) IntervalStatsProto.UsageStats.ChooserAction.COUNTS:
+                    final long token = proto.start(
+                            IntervalStatsProto.UsageStats.ChooserAction.COUNTS);
+                    loadCountsForAction(proto, counts);
+                    proto.end(token);
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    if (action == null) {
+                        // default string
+                        usageStats.mChooserCounts.put("", counts);
+                    }
+                    return;
+            }
+        }
+    }
+
+    private static void loadCountsForAction(ProtoInputStream proto,
+            ArrayMap<String, Integer> counts) throws IOException {
+        String category = null;
+        int count = 0;
+        while (true) {
+            switch (proto.nextField()) {
+                case (int) IntervalStatsProto.UsageStats.ChooserAction.CategoryCount.NAME:
+                    category = proto.readString(
+                            IntervalStatsProto.UsageStats.ChooserAction.CategoryCount.NAME);
+                    break;
+                case (int) IntervalStatsProto.UsageStats.ChooserAction.CategoryCount.COUNT:
+                    count = proto.readInt(
+                            IntervalStatsProto.UsageStats.ChooserAction.CategoryCount.COUNT);
+                    break;
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    if (category == null) {
+                        counts.put("", count);
+                    } else {
+                        counts.put(category, count);
+                    }
+                    return;
+            }
+        }
+    }
+
+    private static void loadConfigStats(ProtoInputStream proto, long fieldId,
+            IntervalStats statsOut) throws IOException {
+        final long token = proto.start(fieldId);
+        boolean configActive = false;
+        final Configuration config = new Configuration();
+        ConfigurationStats configStats;
+        if (proto.isNextField(IntervalStatsProto.Configuration.CONFIG)) {
+            // Fast path reading the configuration. Most cases this should work since it is
+            // written first
+            config.readFromProto(proto, IntervalStatsProto.Configuration.CONFIG);
+            configStats = statsOut.getOrCreateConfigurationStats(config);
+        } else {
+            // Temporarily store collected data to a ConfigurationStats object. This is not
+            // efficient.
+            configStats = new ConfigurationStats();
+        }
+        while (true) {
+            switch (proto.nextField()) {
+                case (int) IntervalStatsProto.Configuration.CONFIG:
+                    // Fast path failed from some reason, add ConfigStats object to statsOut now
+                    config.readFromProto(proto, IntervalStatsProto.Configuration.CONFIG);
+                    final ConfigurationStats temp = statsOut.getOrCreateConfigurationStats(config);
+                    temp.mLastTimeActive = configStats.mLastTimeActive;
+                    temp.mTotalTimeActive = configStats.mTotalTimeActive;
+                    temp.mActivationCount = configStats.mActivationCount;
+                    configStats = temp;
+                    break;
+                case (int) IntervalStatsProto.Configuration.LAST_TIME_ACTIVE_MS:
+                    configStats.mLastTimeActive = statsOut.beginTime + proto.readLong(
+                            IntervalStatsProto.Configuration.LAST_TIME_ACTIVE_MS);
+                    break;
+                case (int) IntervalStatsProto.Configuration.TOTAL_TIME_ACTIVE_MS:
+                    configStats.mTotalTimeActive = proto.readLong(
+                            IntervalStatsProto.Configuration.TOTAL_TIME_ACTIVE_MS);
+                    break;
+                case (int) IntervalStatsProto.Configuration.COUNT:
+                    configStats.mActivationCount = proto.readInt(
+                            IntervalStatsProto.Configuration.COUNT);
+                    break;
+                case (int) IntervalStatsProto.Configuration.ACTIVE:
+                    configActive = proto.readBoolean(IntervalStatsProto.Configuration.ACTIVE);
+                    break;
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    if (configStats.mLastTimeActive == 0) {
+                        //mLastTimeActive was not assigned, assume default value of 0 plus beginTime
+                        configStats.mLastTimeActive = statsOut.beginTime;
+                    }
+                    if (configActive) {
+                        statsOut.activeConfiguration = configStats.mConfiguration;
+                    }
+                    proto.end(token);
+                    return;
+            }
+        }
+    }
+
+    private static void loadEvent(ProtoInputStream proto, long fieldId, IntervalStats statsOut,
+            List<String> stringPool) throws IOException {
+        final long token = proto.start(fieldId);
+        UsageEvents.Event event = statsOut.buildEvent(proto, stringPool);
+        proto.end(token);
+        if (event.mPackage == null) {
+            throw new ProtocolException("no package field present");
+        }
+
+        if (statsOut.events == null) {
+            statsOut.events = new EventList();
+        }
+        statsOut.events.insert(event);
+    }
+
+    private static void writeStringPool(ProtoOutputStream proto, final IntervalStats stats)
+            throws IOException {
+        final long token = proto.start(IntervalStatsProto.STRINGPOOL);
+        final int size = stats.mStringCache.size();
+        proto.write(IntervalStatsProto.StringPool.SIZE, size);
+        for (int i = 0; i < size; i++) {
+            proto.write(IntervalStatsProto.StringPool.STRINGS, stats.mStringCache.valueAt(i));
+        }
+        proto.end(token);
+    }
+
+    private static void writeUsageStats(ProtoOutputStream proto, long fieldId,
+            final IntervalStats stats, final UsageStats usageStats) throws IOException {
+        final long token = proto.start(fieldId);
+        // Write the package name first, so loadUsageStats can avoid creating an extra object
+        final int packageIndex = stats.mStringCache.indexOf(usageStats.mPackageName);
+        if (packageIndex >= 0) {
+            proto.write(IntervalStatsProto.UsageStats.PACKAGE_INDEX, packageIndex + 1);
+        } else {
+            // Package not in Stringpool for some reason, write full string instead
+            Slog.w(TAG, "UsageStats package name (" + usageStats.mPackageName
+                    + ") not found in IntervalStats string cache");
+            proto.write(IntervalStatsProto.UsageStats.PACKAGE, usageStats.mPackageName);
+        }
+        proto.write(IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS,
+                usageStats.mLastTimeUsed - stats.beginTime);
+        proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS,
+                usageStats.mTotalTimeInForeground);
+        proto.write(IntervalStatsProto.UsageStats.LAST_EVENT, usageStats.mLastEvent);
+        proto.write(IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT, usageStats.mAppLaunchCount);
+        writeChooserCounts(proto, usageStats);
+        proto.end(token);
+    }
+
+    private static void writeCountAndTime(ProtoOutputStream proto, long fieldId, int count,
+            long time) throws IOException {
+        final long token = proto.start(fieldId);
+        proto.write(IntervalStatsProto.CountAndTime.COUNT, count);
+        proto.write(IntervalStatsProto.CountAndTime.TIME_MS, time);
+        proto.end(token);
+    }
+
+
+    private static void writeChooserCounts(ProtoOutputStream proto, final UsageStats usageStats)
+            throws IOException {
+        if (usageStats == null || usageStats.mChooserCounts == null
+                || usageStats.mChooserCounts.keySet().isEmpty()) {
+            return;
+        }
+        final int chooserCountSize = usageStats.mChooserCounts.size();
+        for (int i = 0; i < chooserCountSize; i++) {
+            final String action = usageStats.mChooserCounts.keyAt(i);
+            final ArrayMap<String, Integer> counts = usageStats.mChooserCounts.valueAt(i);
+            if (action == null || counts == null || counts.isEmpty()) {
+                continue;
+            }
+            final long token = proto.start(IntervalStatsProto.UsageStats.CHOOSER_ACTIONS);
+            proto.write(IntervalStatsProto.UsageStats.ChooserAction.NAME, action);
+            writeCountsForAction(proto, counts);
+            proto.end(token);
+        }
+    }
+
+    private static void writeCountsForAction(ProtoOutputStream proto,
+            ArrayMap<String, Integer> counts) throws IOException {
+        final int countsSize = counts.size();
+        for (int i = 0; i < countsSize; i++) {
+            String key = counts.keyAt(i);
+            int count = counts.valueAt(i);
+            if (count > 0) {
+                final long token = proto.start(IntervalStatsProto.UsageStats.ChooserAction.COUNTS);
+                proto.write(IntervalStatsProto.UsageStats.ChooserAction.CategoryCount.NAME, key);
+                proto.write(IntervalStatsProto.UsageStats.ChooserAction.CategoryCount.COUNT, count);
+                proto.end(token);
+            }
+        }
+    }
+
+    private static void writeConfigStats(ProtoOutputStream proto, long fieldId,
+            final IntervalStats stats, final ConfigurationStats configStats, boolean isActive)
+            throws IOException {
+        final long token = proto.start(fieldId);
+        configStats.mConfiguration.writeToProto(proto, IntervalStatsProto.Configuration.CONFIG);
+        proto.write(IntervalStatsProto.Configuration.LAST_TIME_ACTIVE_MS,
+                configStats.mLastTimeActive - stats.beginTime);
+        proto.write(IntervalStatsProto.Configuration.TOTAL_TIME_ACTIVE_MS,
+                configStats.mTotalTimeActive);
+        proto.write(IntervalStatsProto.Configuration.COUNT, configStats.mActivationCount);
+        proto.write(IntervalStatsProto.Configuration.ACTIVE, isActive);
+        proto.end(token);
+
+    }
+
+    private static void writeEvent(ProtoOutputStream proto, long fieldId, final IntervalStats stats,
+            final UsageEvents.Event event) throws IOException {
+        final long token = proto.start(fieldId);
+        final int packageIndex = stats.mStringCache.indexOf(event.mPackage);
+        if (packageIndex >= 0) {
+            proto.write(IntervalStatsProto.Event.PACKAGE_INDEX, packageIndex + 1);
+        } else {
+            // Package not in Stringpool for some reason, write full string instead
+            Slog.w(TAG, "Usage event package name (" + event.mPackage
+                    + ") not found in IntervalStats string cache");
+            proto.write(IntervalStatsProto.Event.PACKAGE, event.mPackage);
+        }
+        if (event.mClass != null) {
+            final int classIndex = stats.mStringCache.indexOf(event.mClass);
+            if (classIndex >= 0) {
+                proto.write(IntervalStatsProto.Event.CLASS_INDEX, classIndex + 1);
+            } else {
+                // Class not in Stringpool for some reason, write full string instead
+                Slog.w(TAG, "Usage event class name (" + event.mClass
+                        + ") not found in IntervalStats string cache");
+                proto.write(IntervalStatsProto.Event.CLASS, event.mClass);
+            }
+        }
+        proto.write(IntervalStatsProto.Event.TIME_MS, event.mTimeStamp - stats.beginTime);
+        proto.write(IntervalStatsProto.Event.FLAGS, event.mFlags);
+        proto.write(IntervalStatsProto.Event.TYPE, event.mEventType);
+        switch (event.mEventType) {
+            case UsageEvents.Event.CONFIGURATION_CHANGE:
+                if (event.mConfiguration != null) {
+                    event.mConfiguration.writeToProto(proto, IntervalStatsProto.Event.CONFIG);
+                }
+                break;
+            case UsageEvents.Event.SHORTCUT_INVOCATION:
+                if (event.mShortcutId != null) {
+                    proto.write(IntervalStatsProto.Event.SHORTCUT_ID, event.mShortcutId);
+                }
+                break;
+            case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
+                if (event.mBucketAndReason != 0) {
+                    proto.write(IntervalStatsProto.Event.STANDBY_BUCKET, event.mBucketAndReason);
+                }
+                break;
+            case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+                if (event.mNotificationChannelId != null) {
+                    final int channelIndex = stats.mStringCache.indexOf(
+                            event.mNotificationChannelId);
+                    if (channelIndex >= 0) {
+                        proto.write(IntervalStatsProto.Event.NOTIFICATION_CHANNEL_INDEX,
+                                channelIndex + 1);
+                    } else {
+                        // Channel not in Stringpool for some reason, write full string instead
+                        Slog.w(TAG, "Usage event notification channel name ("
+                                + event.mNotificationChannelId
+                                + ") not found in IntervalStats string cache");
+                        proto.write(IntervalStatsProto.Event.NOTIFICATION_CHANNEL,
+                                event.mNotificationChannelId);
+                    }
+                }
+                break;
+        }
+        proto.end(token);
+    }
+
+    /**
+     * Reads from the {@link ProtoInputStream}.
+     *
+     * @param proto    The proto from which to read events.
+     * @param statsOut The stats object to populate with the data from the XML file.
+     */
+    public static void read(InputStream in, IntervalStats statsOut) throws IOException {
+        final ProtoInputStream proto = new ProtoInputStream(in);
+        List<String> stringPool = null;
+
+        statsOut.packageStats.clear();
+        statsOut.configurations.clear();
+        statsOut.activeConfiguration = null;
+
+        if (statsOut.events != null) {
+            statsOut.events.clear();
+        }
+
+        while (true) {
+            switch (proto.nextField()) {
+                case (int) IntervalStatsProto.END_TIME_MS:
+                    statsOut.endTime = statsOut.beginTime + proto.readLong(
+                            IntervalStatsProto.END_TIME_MS);
+                    break;
+                case (int) IntervalStatsProto.INTERACTIVE:
+                    loadCountAndTime(proto, IntervalStatsProto.INTERACTIVE,
+                            statsOut.interactiveTracker);
+                    break;
+                case (int) IntervalStatsProto.NON_INTERACTIVE:
+                    loadCountAndTime(proto, IntervalStatsProto.NON_INTERACTIVE,
+                            statsOut.nonInteractiveTracker);
+                    break;
+                case (int) IntervalStatsProto.KEYGUARD_SHOWN:
+                    loadCountAndTime(proto, IntervalStatsProto.KEYGUARD_SHOWN,
+                            statsOut.keyguardShownTracker);
+                    break;
+                case (int) IntervalStatsProto.KEYGUARD_HIDDEN:
+                    loadCountAndTime(proto, IntervalStatsProto.KEYGUARD_HIDDEN,
+                            statsOut.keyguardHiddenTracker);
+                    break;
+                case (int) IntervalStatsProto.STRINGPOOL:
+                    stringPool = readStringPool(proto);
+                    statsOut.mStringCache.addAll(stringPool);
+                    break;
+                case (int) IntervalStatsProto.PACKAGES:
+                    loadUsageStats(proto, IntervalStatsProto.PACKAGES, statsOut, stringPool);
+                    break;
+                case (int) IntervalStatsProto.CONFIGURATIONS:
+                    loadConfigStats(proto, IntervalStatsProto.CONFIGURATIONS, statsOut);
+                    break;
+                case (int) IntervalStatsProto.EVENT_LOG:
+                    loadEvent(proto, IntervalStatsProto.EVENT_LOG, statsOut, stringPool);
+                    break;
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    if (statsOut.endTime == 0) {
+                        // endTime not assigned, assume default value of 0 plus beginTime
+                        statsOut.endTime = statsOut.beginTime;
+                    }
+                    return;
+            }
+        }
+    }
+
+    /**
+     * Writes the stats object to an ProtoBuf file.
+     *
+     * @param proto The serializer to which to write the packageStats data.
+     * @param stats The stats object to write to the XML file.
+     */
+    public static void write(OutputStream out, IntervalStats stats) throws IOException {
+        final ProtoOutputStream proto = new ProtoOutputStream(out);
+        proto.write(IntervalStatsProto.END_TIME_MS, stats.endTime - stats.beginTime);
+        // String pool should be written before the rest of the usage stats
+        writeStringPool(proto, stats);
+
+        writeCountAndTime(proto, IntervalStatsProto.INTERACTIVE, stats.interactiveTracker.count,
+                stats.interactiveTracker.duration);
+        writeCountAndTime(proto, IntervalStatsProto.NON_INTERACTIVE,
+                stats.nonInteractiveTracker.count, stats.nonInteractiveTracker.duration);
+        writeCountAndTime(proto, IntervalStatsProto.KEYGUARD_SHOWN,
+                stats.keyguardShownTracker.count, stats.keyguardShownTracker.duration);
+        writeCountAndTime(proto, IntervalStatsProto.KEYGUARD_HIDDEN,
+                stats.keyguardHiddenTracker.count, stats.keyguardHiddenTracker.duration);
+
+        final int statsCount = stats.packageStats.size();
+        for (int i = 0; i < statsCount; i++) {
+            writeUsageStats(proto, IntervalStatsProto.PACKAGES, stats,
+                    stats.packageStats.valueAt(i));
+        }
+        final int configCount = stats.configurations.size();
+        for (int i = 0; i < configCount; i++) {
+            boolean active = stats.activeConfiguration.equals(stats.configurations.keyAt(i));
+            writeConfigStats(proto, IntervalStatsProto.CONFIGURATIONS, stats,
+                    stats.configurations.valueAt(i), active);
+        }
+        final int eventCount = stats.events != null ? stats.events.size() : 0;
+        for (int i = 0; i < eventCount; i++) {
+            writeEvent(proto, IntervalStatsProto.EVENT_LOG, stats, stats.events.get(i));
+        }
+
+        proto.flush();
+    }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXml.java b/services/usage/java/com/android/server/usage/UsageStatsXml.java
index e7db741..f8d1113 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXml.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXml.java
@@ -19,6 +19,9 @@
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 import org.xmlpull.v1.XmlPullParser;
@@ -33,61 +36,7 @@
     private static final String VERSION_ATTR = "version";
     static final String CHECKED_IN_SUFFIX = "-c";
 
-    public static long parseBeginTime(AtomicFile file) throws IOException {
-        return parseBeginTime(file.getBaseFile());
-    }
-
-    public static long parseBeginTime(File file) throws IOException {
-        String name = file.getName();
-
-        // Eat as many occurrences of -c as possible. This is due to a bug where -c
-        // would be appended more than once to a checked-in file, causing a crash
-        // on boot when indexing files since Long.parseLong() will puke on anything but
-        // a number.
-        while (name.endsWith(CHECKED_IN_SUFFIX)) {
-            name = name.substring(0, name.length() - CHECKED_IN_SUFFIX.length());
-        }
-
-        try {
-            return Long.parseLong(name);
-        } catch (NumberFormatException e) {
-            throw new IOException(e);
-        }
-    }
-
-    public static void read(AtomicFile file, IntervalStats statsOut) throws IOException {
-        try {
-            FileInputStream in = file.openRead();
-            try {
-                statsOut.beginTime = parseBeginTime(file);
-                read(in, statsOut);
-                statsOut.lastTimeSaved = file.getLastModifiedTime();
-            } finally {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                    // Empty
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Slog.e(TAG, "UsageStats Xml", e);
-            throw e;
-        }
-    }
-
-    public static void write(AtomicFile file, IntervalStats stats) throws IOException {
-        FileOutputStream fos = file.startWrite();
-        try {
-            write(fos, stats);
-            file.finishWrite(fos);
-            fos = null;
-        } finally {
-            // When fos is null (successful write), this will no-op
-            file.failWrite(fos);
-        }
-    }
-
-    static void read(InputStream in, IntervalStats statsOut) throws IOException {
+    public static void read(InputStream in, IntervalStats statsOut) throws IOException {
         XmlPullParser parser = Xml.newPullParser();
         try {
             parser.setInput(in, "utf-8");
@@ -113,7 +62,7 @@
         }
     }
 
-    static void write(OutputStream out, IntervalStats stats) throws IOException {
+    public static void write(OutputStream out, IntervalStats stats) throws IOException {
         FastXmlSerializer xml = new FastXmlSerializer();
         xml.setOutput(out, "utf-8");
         xml.startDocument("utf-8", true);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index 6a1e97a..a68f9d3 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -196,11 +196,7 @@
                 event.mNotificationChannelId = (channelId != null) ? channelId.intern() : null;
                 break;
         }
-
-        if (statsOut.events == null) {
-            statsOut.events = new EventList();
-        }
-        statsOut.events.insert(event);
+        statsOut.addEvent(event);
     }
 
     private static void writeUsageStats(XmlSerializer xml, final IntervalStats stats,
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 9b194e9..1a8aba0 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -176,12 +176,8 @@
                     currentDailyStats.activeConfiguration, newFullConfig);
         }
 
-        // Add the event to the daily list.
-        if (currentDailyStats.events == null) {
-            currentDailyStats.events = new EventList();
-        }
         if (event.mEventType != UsageEvents.Event.SYSTEM_INTERACTION) {
-            currentDailyStats.events.insert(event);
+            currentDailyStats.addEvent(event);
         }
 
         boolean incrementAppLaunch = false;
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 57f1668..8d6dccc 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;
@@ -52,6 +50,7 @@
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.BatteryManager;
+import android.os.Binder;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -82,6 +81,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 +540,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 +659,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) {
@@ -1982,7 +1995,7 @@
                     + currentAccessory;
             throw new IllegalArgumentException(error);
         }
-        settings.checkPermission(accessory);
+        settings.checkPermission(accessory, Binder.getCallingUid());
         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..5bf94af
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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);
+
+            PackageInfo pkg;
+            try {
+                pkg = mContext.getPackageManager().getPackageInfo(packageName, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                throw new RemoteException("package " + packageName + " cannot be found");
+            }
+
+            if (pkg.applicationInfo.targetSdkVersion >= 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..4be70af 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -318,8 +318,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 +334,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 +430,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 +446,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/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index c5d6dc7..99ad1f4 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -19,6 +19,8 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+
+import com.android.internal.app.IVoiceActionCheckCallback;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import android.app.AppGlobals;
 import android.content.ComponentName;
@@ -1128,6 +1130,27 @@
             }
         }
 
+        @Override
+        public void getActiveServiceSupportedActions(List<String> voiceActions,
+                IVoiceActionCheckCallback callback) {
+            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
+            synchronized (this) {
+                if (mImpl == null) {
+                    try {
+                        callback.onComplete(null);
+                    } catch (RemoteException e) {
+                    }
+                    return;
+                }
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mImpl.getActiveServiceSupportedActions(voiceActions, callback);
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
         public void onSessionShown() {
             synchronized (this) {
                 final int size = mVoiceInteractionSessionListeners.beginBroadcast();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 57e9f66..61d7d6c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -25,6 +25,8 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
+
+import com.android.internal.app.IVoiceActionCheckCallback;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
@@ -57,6 +59,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
     final static String TAG = "VoiceInteractionServiceManager";
@@ -177,6 +180,23 @@
                 activityTokens);
     }
 
+    public void getActiveServiceSupportedActions(List<String> commands,
+            IVoiceActionCheckCallback callback) {
+        if (mService == null) {
+            Slog.w(TAG, "Not bound to voice interaction service " + mComponent);
+            try {
+                callback.onComplete(null);
+            } catch (RemoteException e) {
+            }
+            return;
+        }
+        try {
+            mService.getActiveServiceSupportedActions(commands, callback);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while calling getActiveServiceSupportedActions", e);
+        }
+    }
+
     public boolean hideSessionLocked() {
         if (mActiveSession != null) {
             return mActiveSession.hideLocked();
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/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/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..4ba44a9
--- /dev/null
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
@@ -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.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)
+        }
+    }
+
+    @Test
+    fun testOnPackageEvent() {
+        testAnyMethod { requestId : RequestId ->
+            iorapService.onPackageEvent(requestId,
+                    PackageEvent.createReplaced(
+                            Uri.parse("https://www.google.com"), "com.fake.package"))
+        }
+    }
+
+    @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
new file mode 100644
index 0000000..c3e9184
--- /dev/null
+++ b/startop/tools/view_compiler/Android.bp
@@ -0,0 +1,49 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_host_static {
+    name: "libviewcompiler",
+    srcs: [
+        "java_lang_builder.cc",
+        "util.cc",
+    ],
+    static_libs: [
+        "libbase"
+    ]
+}
+
+cc_binary_host {
+    name: "viewcompiler",
+    srcs: [
+        "main.cc",
+    ],
+    static_libs: [
+        "libbase",
+        "libtinyxml2",
+        "libgflags",
+        "libviewcompiler",
+    ],
+}
+
+cc_test_host {
+    name: "view-compiler-tests",
+    srcs: [
+        "util_test.cc",
+    ],
+    static_libs: [
+        "libviewcompiler",
+    ]
+}
diff --git a/startop/tools/view_compiler/README.md b/startop/tools/view_compiler/README.md
new file mode 100644
index 0000000..5659501
--- /dev/null
+++ b/startop/tools/view_compiler/README.md
@@ -0,0 +1,25 @@
+# View Compiler
+
+This directory contains an experimental compiler for layout files.
+
+It will take a layout XML file and produce a CompiledLayout.java file with a
+specialized layout inflation function.
+
+To use it, let's assume you had a layout in `my_layout.xml` and your app was in
+the Java language package `com.example.myapp`. Run the following command:
+
+    viewcompiler my_layout.xml --package com.example.myapp --out CompiledView.java
+
+This will produce a `CompiledView.java`, which can then be compiled into your
+Android app. Then to use it, in places where you would have inflated
+`R.layouts.my_layout`, instead call `CompiledView.inflate`.
+
+Precompiling views like this generally improves the time needed to inflate them.
+
+This tool is still in its early stages and has a number of limitations.
+* Currently only one layout can be compiled at a time.
+* `merge` and `include` nodes are not supported.
+* View compilation is a manual process that requires code changes in the
+  application.
+* This only works for apps that do not use a custom layout inflater.
+* Other limitations yet to be discovered.
diff --git a/startop/tools/view_compiler/TEST_MAPPING b/startop/tools/view_compiler/TEST_MAPPING
new file mode 100644
index 0000000..cc4b17a
--- /dev/null
+++ b/startop/tools/view_compiler/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "view-compiler-tests"
+    }
+  ]
+}
diff --git a/startop/tools/view_compiler/java_lang_builder.cc b/startop/tools/view_compiler/java_lang_builder.cc
new file mode 100644
index 0000000..0b8754f
--- /dev/null
+++ b/startop/tools/view_compiler/java_lang_builder.cc
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "java_lang_builder.h"
+
+#include "android-base/stringprintf.h"
+
+using android::base::StringPrintf;
+using std::string;
+
+void JavaLangViewBuilder::Start() const {
+  out_ << StringPrintf("package %s;\n", package_.c_str())
+       << "import android.content.Context;\n"
+          "import android.content.res.Resources;\n"
+          "import android.content.res.XmlResourceParser;\n"
+          "import android.util.AttributeSet;\n"
+          "import android.util.Xml;\n"
+          "import android.view.*;\n"
+          "import android.widget.*;\n"
+          "\n"
+          "public final class CompiledView {\n"
+          "\n"
+          "static <T extends View> T createView(Context context, AttributeSet attrs, View parent, "
+          "String name, LayoutInflater.Factory factory, LayoutInflater.Factory2 factory2) {"
+          "\n"
+          "  if (factory2 != null) {\n"
+          "    return (T)factory2.onCreateView(parent, name, context, attrs);\n"
+          "  } else if (factory != null) {\n"
+          "    return (T)factory.onCreateView(name, context, attrs);\n"
+          "  }\n"
+          // TODO: find a way to call the private factory
+          "  return null;\n"
+          "}\n"
+          "\n"
+          "  public static View inflate(Context context) {\n"
+          "    try {\n"
+          "      LayoutInflater inflater = LayoutInflater.from(context);\n"
+          "      LayoutInflater.Factory factory = inflater.getFactory();\n"
+          "      LayoutInflater.Factory2 factory2 = inflater.getFactory2();\n"
+          "      Resources res = context.getResources();\n"
+       << StringPrintf("      XmlResourceParser xml = res.getLayout(%s.R.layout.%s);\n",
+                       package_.c_str(),
+                       layout_name_.c_str())
+       << "      AttributeSet attrs = Xml.asAttributeSet(xml);\n"
+          // The Java-language XmlPullParser needs a call to next to find the start document tag.
+          "      xml.next(); // start document\n";
+}
+
+void JavaLangViewBuilder::Finish() const {
+  out_ << "    } catch (Exception e) {\n"
+          "      return null;\n"
+          "    }\n"  // end try
+          "  }\n"    // end inflate
+          "}\n";     // end CompiledView
+}
+
+void JavaLangViewBuilder::StartView(const string& class_name) {
+  const string view_var = MakeVar("view");
+  const string layout_var = MakeVar("layout");
+  std::string parent = "null";
+  if (!view_stack_.empty()) {
+    const StackEntry& parent_entry = view_stack_.back();
+    parent = parent_entry.view_var;
+  }
+  out_ << "      xml.next(); // <" << class_name << ">\n"
+       << StringPrintf("      %s %s = createView(context, attrs, %s, \"%s\", factory, factory2);\n",
+                       class_name.c_str(),
+                       view_var.c_str(),
+                       parent.c_str(),
+                       class_name.c_str())
+       << StringPrintf("      if (%s == null) %s = new %s(context, attrs);\n",
+                       view_var.c_str(),
+                       view_var.c_str(),
+                       class_name.c_str());
+  if (!view_stack_.empty()) {
+    out_ << StringPrintf("      ViewGroup.LayoutParams %s = %s.generateLayoutParams(attrs);\n",
+                         layout_var.c_str(),
+                         parent.c_str());
+  }
+  view_stack_.push_back({class_name, view_var, layout_var});
+}
+
+void JavaLangViewBuilder::FinishView() {
+  const StackEntry var = view_stack_.back();
+  view_stack_.pop_back();
+  if (!view_stack_.empty()) {
+    const string& parent = view_stack_.back().view_var;
+    out_ << StringPrintf("      xml.next(); // </%s>\n", var.class_name.c_str())
+         << StringPrintf("      %s.addView(%s, %s);\n",
+                         parent.c_str(),
+                         var.view_var.c_str(),
+                         var.layout_params_var.c_str());
+  } else {
+    out_ << StringPrintf("      return %s;\n", var.view_var.c_str());
+  }
+}
+
+const std::string JavaLangViewBuilder::MakeVar(std::string prefix) {
+  std::stringstream v;
+  v << prefix << view_id_++;
+  return v.str();
+}
diff --git a/startop/tools/view_compiler/java_lang_builder.h b/startop/tools/view_compiler/java_lang_builder.h
new file mode 100644
index 0000000..c8d20b2
--- /dev/null
+++ b/startop/tools/view_compiler/java_lang_builder.h
@@ -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.
+ */
+#ifndef JAVA_LANG_BUILDER_H_
+#define JAVA_LANG_BUILDER_H_
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+// Build Java language code to instantiate views.
+//
+// This has a very small interface to make it easier to generate additional
+// backends, such as a direct-to-DEX version.
+class JavaLangViewBuilder {
+ public:
+  JavaLangViewBuilder(std::string package, std::string layout_name, std::ostream& out = std::cout)
+      : package_(package), layout_name_(layout_name), out_(out) {}
+
+  // Begin generating a class. Adds the package boilerplate, etc.
+  void Start() const;
+  // Finish generating a class, closing off any open curly braces, etc.
+  void Finish() const;
+
+  // Begin creating a view (i.e. process the opening tag)
+  void StartView(const std::string& class_name);
+  // Finish a view, after all of its child nodes have been processed.
+  void FinishView();
+
+ private:
+  const std::string MakeVar(std::string prefix);
+
+  std::string const package_;
+  std::string const layout_name_;
+
+  std::ostream& out_;
+
+  size_t view_id_ = 0;
+
+  struct StackEntry {
+      // The class name for this view object
+      const std::string class_name;
+
+      // The variable name that is holding the view object
+      const std::string view_var;
+
+      // The variable name that holds the object's layout parameters
+      const std::string layout_params_var;
+  };
+  std::vector<StackEntry> view_stack_;
+};
+
+#endif  // JAVA_LANG_BUILDER_H_
diff --git a/startop/tools/view_compiler/main.cc b/startop/tools/view_compiler/main.cc
new file mode 100644
index 0000000..0ad7e24
--- /dev/null
+++ b/startop/tools/view_compiler/main.cc
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "gflags/gflags.h"
+
+#include "java_lang_builder.h"
+#include "util.h"
+
+#include "tinyxml2.h"
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+using namespace tinyxml2;
+using std::string;
+
+constexpr char kStdoutFilename[]{"stdout"};
+
+DEFINE_string(package, "", "The package name for the generated class (required)");
+DEFINE_string(out, kStdoutFilename, "Where to write the generated class");
+
+namespace {
+class ViewCompilerXmlVisitor : public XMLVisitor {
+ public:
+  ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
+
+  bool VisitEnter(const XMLDocument& /*doc*/) override {
+    builder_->Start();
+    return true;
+  }
+
+  bool VisitExit(const XMLDocument& /*doc*/) override {
+    builder_->Finish();
+    return true;
+  }
+
+  bool VisitEnter(const XMLElement& element, const XMLAttribute* /*firstAttribute*/) override {
+    builder_->StartView(element.Name());
+    return true;
+  }
+
+  bool VisitExit(const XMLElement& /*element*/) override {
+    builder_->FinishView();
+    return true;
+  }
+
+ private:
+  JavaLangViewBuilder* builder_;
+};
+}  // end namespace
+
+int main(int argc, char** argv) {
+  constexpr size_t kProgramName = 0;
+  constexpr size_t kFileNameParam = 1;
+  constexpr size_t kNumRequiredArgs = 2;
+
+  gflags::SetUsageMessage(
+      "Compile XML layout files into equivalent Java language code\n"
+      "\n"
+      "  example usage:  viewcompiler layout.xml --package com.example.androidapp");
+  gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags*/ true);
+
+  gflags::CommandLineFlagInfo cmd = gflags::GetCommandLineFlagInfoOrDie("package");
+  if (argc != kNumRequiredArgs || cmd.is_default) {
+    gflags::ShowUsageWithFlags(argv[kProgramName]);
+    return 1;
+  }
+
+  const char* const filename = argv[kFileNameParam];
+  const string layout_name = FindLayoutNameFromFilename(filename);
+
+  // We want to generate Java language code to inflate exactly this layout. This means
+  // generating code to walk the resource XML too.
+
+  XMLDocument xml;
+  xml.LoadFile(filename);
+
+  std::ofstream outfile;
+  if (FLAGS_out != kStdoutFilename) {
+    outfile.open(FLAGS_out);
+  }
+  JavaLangViewBuilder builder{
+      FLAGS_package, layout_name, FLAGS_out == kStdoutFilename ? std::cout : outfile};
+
+  ViewCompilerXmlVisitor visitor{&builder};
+  xml.Accept(&visitor);
+
+  return 0;
+}
\ No newline at end of file
diff --git a/startop/tools/view_compiler/util.cc b/startop/tools/view_compiler/util.cc
new file mode 100644
index 0000000..69df41d
--- /dev/null
+++ b/startop/tools/view_compiler/util.cc
@@ -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.
+ */
+
+#include "util.h"
+
+using std::string;
+
+// TODO: see if we can borrow this from somewhere else, like aapt2.
+string FindLayoutNameFromFilename(const string& filename) {
+  size_t start = filename.rfind("/");
+  if (start == string::npos) {
+    start = 0;
+  } else {
+    start++;  // advance past '/' character
+  }
+  size_t end = filename.find(".", start);
+
+  return filename.substr(start, end - start);
+}
diff --git a/startop/tools/view_compiler/util.h b/startop/tools/view_compiler/util.h
new file mode 100644
index 0000000..03e0939
--- /dev/null
+++ b/startop/tools/view_compiler/util.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UTIL_H_
+#define UTIL_H_
+
+#include <string>
+
+std::string FindLayoutNameFromFilename(const std::string& filename);
+
+#endif  // UTIL_H_
diff --git a/startop/tools/view_compiler/util_test.cc b/startop/tools/view_compiler/util_test.cc
new file mode 100644
index 0000000..d1540d3
--- /dev/null
+++ b/startop/tools/view_compiler/util_test.cc
@@ -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.
+ */
+
+#include "util.h"
+
+#include "gtest/gtest.h"
+
+using std::string;
+
+TEST(UtilTest, FindLayoutNameFromFilename) {
+  EXPECT_EQ("bar", ::FindLayoutNameFromFilename("foo/bar.xml"));
+  EXPECT_EQ("bar", ::FindLayoutNameFromFilename("bar.xml"));
+  EXPECT_EQ("bar", ::FindLayoutNameFromFilename("./foo/bar.xml"));
+  EXPECT_EQ("bar", ::FindLayoutNameFromFilename("/foo/bar.xml"));
+}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 096cf37..08bc9bc 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -141,6 +141,8 @@
      * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to
      * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EVENT_REQUEST_HANDOVER =
             "android.telecom.event.REQUEST_HANDOVER";
@@ -149,6 +151,8 @@
      * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event.  Specifies the
      * {@link PhoneAccountHandle} to which a call should be handed over to.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE =
             "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE";
@@ -161,6 +165,8 @@
      * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and
      * {@link VideoProfile#STATE_TX_ENABLED}.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EXTRA_HANDOVER_VIDEO_STATE =
             "android.telecom.extra.HANDOVER_VIDEO_STATE";
@@ -176,6 +182,8 @@
      * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
      * is called to initate the handover.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS";
 
@@ -186,6 +194,8 @@
      * <p>
      * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EVENT_HANDOVER_COMPLETE =
             "android.telecom.event.HANDOVER_COMPLETE";
@@ -198,6 +208,8 @@
      * <p>
      * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
             "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
@@ -209,6 +221,8 @@
      * <p>
      * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EVENT_HANDOVER_FAILED =
             "android.telecom.event.HANDOVER_FAILED";
@@ -434,8 +448,15 @@
          */
         public static final int PROPERTY_RTT = 0x00000400;
 
+        /**
+         * Indicates that the call has been identified as the network as an emergency call. This
+         * property may be set for both incoming and outgoing calls which the network identifies as
+         * emergency calls.
+         */
+        public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 0x00000800;
+
         //******************************************************************************************
-        // Next PROPERTY value: 0x00000800
+        // Next PROPERTY value: 0x00001000
         //******************************************************************************************
 
         private final String mTelecomCallId;
@@ -601,6 +622,9 @@
             if(hasProperty(properties, PROPERTY_ASSISTED_DIALING_USED)) {
                 builder.append(" PROPERTY_ASSISTED_DIALING_USED");
             }
+            if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
+                builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL");
+            }
             builder.append("]");
             return builder.toString();
         }
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 024bd30..a39e885 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -22,6 +22,8 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.telecom.Connection.VideoProvider;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
 import android.util.ArraySet;
 
 import java.util.ArrayList;
@@ -573,6 +575,20 @@
     }
 
     /**
+     * Updates RIL voice radio technology used for current conference after its creation.
+     *
+     * @hide
+     */
+    public void updateCallRadioTechAfterCreation() {
+        final Connection primaryConnection = getPrimaryConnection();
+        if (primaryConnection != null) {
+            setCallRadioTech(primaryConnection.getCallRadioTech());
+        } else {
+            Log.w(this, "No primary connection found while updateCallRadioTechAfterCreation");
+        }
+    }
+
+    /**
      * @hide
      * @deprecated Use {@link #setConnectionTime}.
      */
@@ -652,6 +668,37 @@
     }
 
     /**
+     * Sets RIL voice radio technology used for current conference.
+     *
+     * @param vrat the RIL voice radio technology used for current conference,
+     *             see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
+     *
+     * @hide
+     */
+    public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+        putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+                ServiceState.rilRadioTechnologyToNetworkType(vrat));
+    }
+
+    /**
+     * Returns RIL voice radio technology used for current conference.
+     *
+     * @return the RIL voice radio technology used for current conference,
+     *         see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
+     *
+     * @hide
+     */
+    public final @ServiceState.RilRadioTechnology int getCallRadioTech() {
+        int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        Bundle extras = getExtras();
+        if (extras != null) {
+            voiceNetworkType = extras.getInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+                    TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        }
+        return ServiceState.networkTypeToRilRadioTechnology(voiceNetworkType);
+    }
+
+    /**
      * Inform this Conference that the state of its audio output has been changed externally.
      *
      * @param state The new audio state.
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 3d2b397..34603a3 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -38,6 +38,8 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
 import android.util.ArraySet;
 import android.view.Surface;
 
@@ -412,6 +414,13 @@
      */
     public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9;
 
+    /**
+     * Set by the framework to indicate that the network has identified a Connection as an emergency
+     * call.
+     * @hide
+     */
+    public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1 << 10;
+
     //**********************************************************************************************
     // Next PROPERTY value: 1<<10
     //**********************************************************************************************
@@ -585,6 +594,8 @@
      * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has
      * successfully completed.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EVENT_HANDOVER_COMPLETE =
             "android.telecom.event.HANDOVER_COMPLETE";
@@ -594,6 +605,8 @@
      * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has failed
      * to complete.
      * @hide
+     * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+     * APIs instead.
      */
     public static final String EVENT_HANDOVER_FAILED =
             "android.telecom.event.HANDOVER_FAILED";
@@ -801,6 +814,10 @@
             builder.append(isLong ? " PROPERTY_IS_RTT" : " rtt");
         }
 
+        if (can(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
+            builder.append(isLong ? " PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL" : " ecall");
+        }
+
         builder.append("]");
         return builder.toString();
     }
@@ -1885,6 +1902,24 @@
     }
 
     /**
+     * Returns RIL voice radio technology used for current connection.
+     *
+     * @return the RIL voice radio technology used for current connection,
+     *         see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
+     *
+     * @hide
+     */
+    public final @ServiceState.RilRadioTechnology int getCallRadioTech() {
+        int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        Bundle extras = getExtras();
+        if (extras != null) {
+            voiceNetworkType = extras.getInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+                    TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        }
+        return ServiceState.networkTypeToRilRadioTechnology(voiceNetworkType);
+    }
+
+    /**
      * @return The status hints for this connection.
      */
     public final StatusHints getStatusHints() {
@@ -2318,6 +2353,26 @@
     }
 
     /**
+     * Sets RIL voice radio technology used for current connection.
+     *
+     * @param vrat the RIL Voice Radio Technology used for current connection,
+     *             see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
+     *
+     * @hide
+     */
+    public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+        putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+                ServiceState.rilRadioTechnologyToNetworkType(vrat));
+        // Propagates the call radio technology to its parent {@link android.telecom.Conference}
+        // This action only covers non-IMS CS conference calls.
+        // For IMS PS call conference call, it can be updated via its host connection
+        // {@link #Listener.onExtrasChanged} event.
+        if (getConference() != null) {
+            getConference().setCallRadioTech(vrat);
+        }
+    }
+
+    /**
      * Sets the label and icon status to display in the in-call UI.
      *
      * @param statusHints The status label and icon to set.
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 4e22823..d33a537 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -317,6 +317,15 @@
             "android.telecom.extra.CALL_TECHNOLOGY_TYPE";
 
     /**
+     * Optional extra for communicating the call network technology used by a
+     * {@link android.telecom.Connection} to Telecom and InCallUI.
+     *
+     * @see {@code NETWORK_TYPE_*} in {@link android.telephony.TelephonyManager}.
+     */
+    public static final String EXTRA_CALL_NETWORK_TYPE =
+            "android.telecom.extra.CALL_NETWORK_TYPE";
+
+    /**
      * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
      * package name of the app specifying an alternative gateway for the call.
      * The value is a string.
@@ -1875,6 +1884,43 @@
         }
     }
 
+    /**
+     * Determines if there is an ongoing emergency call.  This can be either an outgoing emergency
+     * call, as identified by the dialed number, or because a call was identified by the network
+     * as an emergency call.
+     * @return {@code true} if there is an ongoing emergency call, {@code false} otherwise.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean isInEmergencyCall() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().isInEmergencyCall();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException isInEmergencyCall: " + e);
+            return false;
+        }
+        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 b4e7d56..df7d683 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -279,4 +279,14 @@
      * @see TelecomServiceImpl#acceptHandover
      */
     void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct);
+
+    /**
+     * @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 722df67..4846092 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -1233,6 +1233,17 @@
                           "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
 
             /**
+             * Same as {@link #ACTION_DEFAULT_SMS_PACKAGE_CHANGED} but it's implicit (e.g. sent to
+             * all apps) and requires
+             * {@link android.Manifest.permission#MONITOR_DEFAULT_SMS_PACKAGE} to receive.
+             *
+             * @hide
+             */
+            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+            public static final String ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL =
+                    "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL";
+
+            /**
              * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
              * {@link #DATA_SMS_RECEIVED_ACTION} intent.
              *
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7506d00..fac1943 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -271,6 +271,14 @@
             KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
 
     /**
+     * Do only allow auto selection in Advanced Network Settings when in home network.
+     * Manual selection is allowed when in roaming network.
+     * @hide
+     */
+    public static final String
+            KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network";
+
+    /**
      * Control whether users receive a simplified network settings UI and improved network
      * selection.
      */
@@ -1625,11 +1633,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>
@@ -1966,6 +1984,17 @@
             "skip_cf_fail_to_disable_dialog_bool";
 
     /**
+     * Flag specifying whether operator supports including no reply condition timer option on
+     * CFNRy (3GPP TS 24.082 3: Call Forwarding on No Reply) in the call forwarding settings UI.
+     * {@code true}  - include no reply condition timer option on CFNRy
+     * {@code false} - don't include no reply condition timer option on CFNRy
+     *
+     * @hide
+     */
+    public static final String KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL =
+            "support_no_reply_timer_for_cfnry_bool";
+
+    /**
      * List of the FAC (feature access codes) to dial as a normal call.
      * @hide
      */
@@ -2104,6 +2133,56 @@
     public static final String KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL =
             "config_show_orig_dial_string_for_cdma";
 
+    /**
+     * Flag specifying whether to show notification(call blocking disabled) when Enhanced Call
+     * Blocking(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL) is enabled and making emergency call.
+     * When true, notification is shown always.
+     * When false, notification is shown only when any setting of "Enhanced Blocked number" is
+     * enabled.
+     */
+    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;
 
@@ -2160,6 +2239,7 @@
         sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);
         sDefaults.putBoolean(KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false);
+        sDefaults.putBoolean(KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL, false);
         sDefaults.putBoolean(KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false);
 
@@ -2389,6 +2469,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);
@@ -2418,6 +2499,7 @@
         sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
         sDefaults.putBoolean(KEY_RTT_SUPPORTED_BOOL, false);
         sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false);
+        sDefaults.putBoolean(KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true);
         sDefaults.putStringArray(KEY_FEATURE_ACCESS_CODES_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_IDENTIFY_HIGH_DEFINITION_CALLS_IN_CALL_LOG_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL, false);
@@ -2441,6 +2523,11 @@
                 });
         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/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java
new file mode 100644
index 0000000..e373797
--- /dev/null
+++ b/telephony/java/android/telephony/MbmsGroupCallSession.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 android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.mbms.GroupCall;
+import android.telephony.mbms.GroupCallCallback;
+import android.telephony.mbms.InternalGroupCallCallback;
+import android.telephony.mbms.InternalGroupCallSessionCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsGroupCallSessionCallback;
+import android.telephony.mbms.MbmsUtils;
+import android.telephony.mbms.vendor.IMbmsGroupCallService;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * This class provides functionality for accessing group call functionality over MBMS.
+ */
+public class MbmsGroupCallSession implements AutoCloseable {
+    private static final String LOG_TAG = "MbmsGroupCallSession";
+
+    /**
+     * Service action which must be handled by the middleware implementing the MBMS group call
+     * interface.
+     * @hide
+     */
+    @SystemApi
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String MBMS_GROUP_CALL_SERVICE_ACTION =
+            "android.telephony.action.EmbmsGroupCall";
+
+    /**
+     * Metadata key that specifies the component name of the service to bind to for group calls.
+     * @hide
+     */
+    @TestApi
+    public static final String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA =
+            "mbms-group-call-service-override";
+
+    private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
+
+    private AtomicReference<IMbmsGroupCallService> mService = new AtomicReference<>(null);
+    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+        @Override
+        public void binderDied() {
+            sIsInitialized.set(false);
+            mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+                    "Received death notification");
+        }
+    };
+
+    private InternalGroupCallSessionCallback mInternalCallback;
+    private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>();
+
+    private final Context mContext;
+    private int mSubscriptionId;
+
+    /** @hide */
+    private MbmsGroupCallSession(Context context, Executor executor, int subscriptionId,
+            MbmsGroupCallSessionCallback callback) {
+        mContext = context;
+        mSubscriptionId = subscriptionId;
+        mInternalCallback = new InternalGroupCallSessionCallback(callback, executor);
+    }
+
+    /**
+     * Create a new {@link MbmsGroupCallSession} using the given subscription ID.
+     *
+     * You may only have one instance of {@link MbmsGroupCallSession} per UID. If you call this
+     * method while there is an active instance of {@link MbmsGroupCallSession} in your process
+     * (in other words, one that has not had {@link #close()} called on it), this method will
+     * throw an {@link IllegalStateException}. If you call this method in a different process
+     * running under the same UID, an error will be indicated via
+     * {@link MbmsGroupCallSessionCallback#onError(int, String)}.
+     *
+     * Note that initialization may fail asynchronously. If you wish to try again after you
+     * receive such an asynchronous error, you must call {@link #close()} on the instance of
+     * {@link MbmsGroupCallSession} that you received before calling this method again.
+     *
+     * @param context The {@link Context} to use.
+     * @param executor The executor on which you wish to execute callbacks.
+     * @param subscriptionId The subscription ID to use.
+     * @param callback A callback object on which you wish to receive results of asynchronous
+     *                 operations.
+     * @return An instance of {@link MbmsGroupCallSession}, or null if an error occurred.
+     */
+    public static @Nullable MbmsGroupCallSession create(@NonNull Context context,
+            @NonNull Executor executor, int subscriptionId,
+            final @NonNull MbmsGroupCallSessionCallback callback) {
+        if (!sIsInitialized.compareAndSet(false, true)) {
+            throw new IllegalStateException("Cannot create two instances of MbmsGroupCallSession");
+        }
+        MbmsGroupCallSession session = new MbmsGroupCallSession(context, executor,
+                subscriptionId, callback);
+
+        final int result = session.bindAndInitialize();
+        if (result != MbmsErrors.SUCCESS) {
+            sIsInitialized.set(false);
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    callback.onError(result, null);
+                }
+            });
+            return null;
+        }
+        return session;
+    }
+
+    /**
+     * Create a new {@link MbmsGroupCallSession} using the system default data subscription ID.
+     * See {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)}.
+     */
+    public static MbmsGroupCallSession create(@NonNull Context context,
+            @NonNull Executor executor, @NonNull MbmsGroupCallSessionCallback callback) {
+        return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback);
+    }
+
+    /**
+     * Terminates this instance. Also terminates
+     * any group calls spawned from this instance as if
+     * {@link GroupCall#close()} had been called on them. After this method returns,
+     * no further callbacks originating from the middleware will be enqueued on the provided
+     * instance of {@link MbmsGroupCallSessionCallback}, but callbacks that have already been
+     * enqueued will still be delivered.
+     *
+     * It is safe to call {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)} to
+     * obtain another instance of {@link MbmsGroupCallSession} immediately after this method
+     * returns.
+     *
+     * May throw an {@link IllegalStateException}
+     */
+    public void close() {
+        try {
+            IMbmsGroupCallService groupCallService = mService.get();
+            if (groupCallService == null) {
+                // Ignore and return, assume already disposed.
+                return;
+            }
+            groupCallService.dispose(mSubscriptionId);
+            for (GroupCall s : mKnownActiveGroupCalls) {
+                s.getCallback().stop();
+            }
+            mKnownActiveGroupCalls.clear();
+        } catch (RemoteException e) {
+            // Ignore for now
+        } finally {
+            mService.set(null);
+            sIsInitialized.set(false);
+            mInternalCallback.stop();
+        }
+    }
+
+    /**
+     * Starts the requested group call, reporting status to the indicated callback.
+     * Returns an object used to control that call.
+     *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     *
+     * Asynchronous errors through the callback include any of the errors in
+     * {@link MbmsErrors.GeneralErrors}.
+     *
+     * @param executor The executor on which you wish to execute callbacks for this stream.
+     * @param tmgi The TMGI, an identifier for the group call you want to join.
+     * @param saiArray An array of SAIs for the group call that should be negotiated separately with
+     *                the carrier.
+     * @param frequencyArray An array of frequencies for the group call that should be negotiated
+     *                separately with the carrier.
+     * @param callback The callback that you want to receive information about the call on.
+     * @return An instance of {@link GroupCall} through which the call can be controlled.
+     *         May be {@code null} if an error occurred.
+     */
+    public @Nullable GroupCall startGroupCall(@NonNull Executor executor, long tmgi, int[] saiArray,
+            int[] frequencyArray, @NonNull GroupCallCallback callback) {
+        IMbmsGroupCallService groupCallService = mService.get();
+        if (groupCallService == null) {
+            throw new IllegalStateException("Middleware not yet bound");
+        }
+
+        InternalGroupCallCallback serviceCallback = new InternalGroupCallCallback(
+                callback, executor);
+
+        GroupCall serviceForApp = new GroupCall(mSubscriptionId,
+                groupCallService, this, tmgi, serviceCallback);
+        mKnownActiveGroupCalls.add(serviceForApp);
+
+        try {
+            int returnCode = groupCallService.startGroupCall(
+                    mSubscriptionId, tmgi, saiArray, frequencyArray, serviceCallback);
+            if (returnCode == MbmsErrors.UNKNOWN) {
+                // Unbind and throw an obvious error
+                close();
+                throw new IllegalStateException("Middleware must not return an unknown error code");
+            }
+            if (returnCode != MbmsErrors.SUCCESS) {
+                mInternalCallback.onError(returnCode, null);
+                return null;
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService.set(null);
+            sIsInitialized.set(false);
+            mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+            return null;
+        }
+
+        return serviceForApp;
+    }
+
+    /** @hide */
+    public void onGroupCallStopped(GroupCall service) {
+        mKnownActiveGroupCalls.remove(service);
+    }
+
+    private int bindAndInitialize() {
+        return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION,
+                new ServiceConnection() {
+                    @Override
+                    public void onServiceConnected(ComponentName name, IBinder service) {
+                        IMbmsGroupCallService groupCallService =
+                                IMbmsGroupCallService.Stub.asInterface(service);
+                        int result;
+                        try {
+                            result = groupCallService.initialize(mInternalCallback,
+                                    mSubscriptionId);
+                        } catch (RemoteException e) {
+                            Log.e(LOG_TAG, "Service died before initialization");
+                            mInternalCallback.onError(
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    e.toString());
+                            sIsInitialized.set(false);
+                            return;
+                        } catch (RuntimeException e) {
+                            Log.e(LOG_TAG, "Runtime exception during initialization");
+                            mInternalCallback.onError(
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    e.toString());
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        if (result == MbmsErrors.UNKNOWN) {
+                            // Unbind and throw an obvious error
+                            close();
+                            throw new IllegalStateException("Middleware must not return"
+                                    + " an unknown error code");
+                        }
+                        if (result != MbmsErrors.SUCCESS) {
+                            mInternalCallback.onError(result,
+                                    "Error returned during initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        try {
+                            groupCallService.asBinder().linkToDeath(mDeathRecipient, 0);
+                        } catch (RemoteException e) {
+                            mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+                                    "Middleware lost during initialization");
+                            sIsInitialized.set(false);
+                            return;
+                        }
+                        mService.set(groupCallService);
+                    }
+
+                    @Override
+                    public void onServiceDisconnected(ComponentName name) {
+                        sIsInitialized.set(false);
+                        mService.set(null);
+                    }
+                });
+    }
+}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 8e99518..79298fd 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -32,7 +32,12 @@
 /**
  * Represents the neighboring cell information, including
  * Received Signal Strength and Cell ID location.
+ *
+ * @deprecated This class should not be used by any app targeting
+ *     {@link 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/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java
index 7c7d7a0..202da68 100644
--- a/telephony/java/android/telephony/NetworkScan.java
+++ b/telephony/java/android/telephony/NetworkScan.java
@@ -16,11 +16,10 @@
 
 package android.telephony;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.annotation.IntDef;
-import android.util.Log;
 
 import com.android.internal.telephony.ITelephony;
 
@@ -113,6 +112,8 @@
         }
         try {
             telephony.stopNetworkScan(mSubId, mScanId);
+        } catch (IllegalArgumentException ex) {
+            Rlog.d(TAG,  "stopNetworkScan - no active scan for ScanID=" + mScanId);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "stopNetworkScan  RemoteException", ex);
         } catch (RuntimeException ex) {
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 498be96..3ea018a 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -281,6 +281,16 @@
      */
     public static final int LISTEN_PHONE_CAPABILITY_CHANGE                 = 0x00200000;
 
+    /**
+     *  Listen for changes to preferred data subId.
+     *  See {@link SubscriptionManager#setPreferredData(int)}
+     *  for more details.
+     *
+     *  @see #onPreferredDataSubIdChanged
+     *  @hide
+     */
+    public static final int LISTEN_PREFERRED_DATA_SUBID_CHANGE              = 0x00400000;
+
     /*
      * Subscription used to listen to the phone state changes
      * @hide
@@ -407,6 +417,9 @@
                         PhoneStateListener.this.onPhoneCapabilityChanged(
                                 (PhoneCapability) msg.obj);
                         break;
+                    case LISTEN_PREFERRED_DATA_SUBID_CHANGE:
+                        PhoneStateListener.this.onPreferredDataSubIdChanged((int) msg.obj);
+                        break;
                 }
             }
         };
@@ -647,6 +660,18 @@
     }
 
     /**
+     * Callback invoked when preferred data subId changes. Requires
+     * the READ_PRIVILEGED_PHONE_STATE permission.
+     * @param subId the new preferred data subId. If it's INVALID_SUBSCRIPTION_ID,
+     *              it means it's unset and defaultDataSub is used to determine which
+     *              modem is preferred.
+     * @hide
+     */
+    public void onPreferredDataSubIdChanged(int subId) {
+        // 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
@@ -777,6 +802,11 @@
         public void onPhoneCapabilityChanged(PhoneCapability capability) {
             send(LISTEN_PHONE_CAPABILITY_CHANGE, 0, 0, capability);
         }
+
+        public void onPreferredDataSubIdChanged(int subId) {
+            send(LISTEN_PREFERRED_DATA_SUBID_CHANGE, 0, 0, subId);
+        }
+
     }
 
     /**
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f2b73dc..7469186 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -24,6 +24,7 @@
 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;
@@ -1595,7 +1596,7 @@
     /**
      * Get all of the available network registration states.
      *
-     * @return List of registration states
+     * @return List of {@link NetworkRegistrationState}
      * @hide
      */
     @SystemApi
@@ -1606,14 +1607,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 +1645,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 +1727,4 @@
             mNetworkRegistrationStates.add(regState);
         }
     }
-
 }
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 91e24a9..e40bae1 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -603,7 +603,7 @@
 
     /**
      * Returns the message body as a String, if it exists and is text based.
-     * @return message body is there is one, otherwise null
+     * @return message body if there is one, otherwise null
      */
     public String getMessageBody() {
         return mWrappedSmsMessage.getMessageBody();
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index ec26622..22c1e58 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -33,11 +33,13 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * A Parcelable class for Subscription Information.
@@ -552,11 +554,49 @@
         String cardIdToPrint = givePrintableIccid(mCardId);
         return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
                 + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
-                + " nameSource=" + mNameSource + " iconTint=" + mIconTint
+                + " nameSource=" + mNameSource + " iconTint=" + mIconTint + " mNumber=" + mNumber
                 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
-                + " mnc " + mMnc + " isEmbedded " + mIsEmbedded
+                + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
                 + " accessRules " + Arrays.toString(mAccessRules)
                 + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
                 + " parentSubId=" + mParentSubId + "}";
     }
-}
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
+                mIsOpportunistic, mParentSubId, mIccId, mNumber, mMcc, mMnc, mCountryIso,
+                mCardId, mDisplayName, mCarrierName, mAccessRules);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) return false;
+        if (obj == this) return true;
+
+        SubscriptionInfo toCompare;
+        try {
+            toCompare = (SubscriptionInfo) obj;
+        } catch (ClassCastException ex) {
+            return false;
+        }
+
+        return mId == toCompare.mId
+                && mSimSlotIndex == toCompare.mSimSlotIndex
+                && mNameSource == toCompare.mNameSource
+                && mIconTint == toCompare.mIconTint
+                && mDataRoaming == toCompare.mDataRoaming
+                && mIsEmbedded == toCompare.mIsEmbedded
+                && mIsOpportunistic == toCompare.mIsOpportunistic
+                && mParentSubId == toCompare.mParentSubId
+                && Objects.equals(mIccId, toCompare.mIccId)
+                && Objects.equals(mNumber, toCompare.mNumber)
+                && Objects.equals(mMcc, toCompare.mMcc)
+                && Objects.equals(mMnc, toCompare.mMnc)
+                && Objects.equals(mCountryIso, toCompare.mCountryIso)
+                && Objects.equals(mCardId, toCompare.mCardId)
+                && TextUtils.equals(mDisplayName, toCompare.mDisplayName)
+                && TextUtils.equals(mCarrierName, toCompare.mCarrierName)
+                && Arrays.equals(mAccessRules, toCompare.mAccessRules);
+    }
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index e9423f7..76e6afd 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -90,9 +90,7 @@
     /** @hide */
     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;
 
     /**
@@ -1602,6 +1600,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
@@ -1848,6 +1859,19 @@
     }
 
     /**
+     * Checks if the supplied subscription ID corresponds to an active subscription.
+     *
+     * @param subscriptionId the subscription ID.
+     * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
+     * {@code false} if it does not correspond to an active subscription; or throw a
+     * SecurityException if the caller hasn't got the right permission.
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public boolean isActiveSubscriptionId(int subscriptionId) {
+        return isActiveSubId(subscriptionId);
+    }
+
+    /**
      * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
      * and the SIM providing the subscription is present in a slot and in "LOADED" state.
      * @hide
@@ -1857,7 +1881,7 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                return iSub.isActiveSubId(subId);
+                return iSub.isActiveSubId(subId, mContext.getOpPackageName());
             }
         } catch (RemoteException ex) {
         }
@@ -2136,9 +2160,15 @@
 
     /**
      * Set preferred default data.
-     * Set on which slot default data will be on.
+     * Set on which slot most cellular data will be on.
+     * It's also usually what we set up internet connection on.
      *
-     * @param slotId which slot is preferred to for cellular data.
+     * PreferredData overwrites user setting of default data subscription. And it's used
+     * by AlternativeNetworkAccessService 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.
      * @hide
      *
      */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index fa24796..52c8f5a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import static android.content.Context.TELECOM_SERVICE;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.IntDef;
@@ -65,10 +66,11 @@
 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;
+import com.android.internal.telephony.OperatorInfo;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyProperties;
@@ -165,7 +167,6 @@
     /** @hide */
     static public final int OTASP_SIM_UNPROVISIONED = 5;
 
-
     /** @hide */
     static public final int KEY_TYPE_EPDG = 1;
 
@@ -1200,6 +1201,15 @@
             "android.intent.action.DATA_STALL_DETECTED";
 
     /**
+     * A service action that identifies a {@link android.app.SmsAppService} subclass in the
+     * AndroidManifest.xml.
+     *
+     * <p>See {@link android.app.SmsAppService} for the details.
+     */
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String ACTION_SMS_APP_SERVICE = "android.telephony.action.SMS_APP_SERVICE";
+
+    /**
      * An int extra used with {@link #ACTION_DATA_STALL_DETECTED} to indicate the
      * action associated with the data stall recovery.
      *
@@ -1578,6 +1588,7 @@
      *
      * @return List of NeighboringCellInfo or null if info unavailable.
      *
+     * @removed
      * @deprecated Use {@link #getAllCellInfo} which returns a superset of the information
      *             from NeighboringCellInfo, including LTE cell information.
      */
@@ -2090,10 +2101,37 @@
 
     /** Max network type number. Update as new types are added. Don't add negative types. {@hide} */
     public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_LTE_CA;
+
+    /** @hide */
+    @IntDef({
+            NETWORK_TYPE_UNKNOWN,
+            NETWORK_TYPE_GPRS,
+            NETWORK_TYPE_EDGE,
+            NETWORK_TYPE_UMTS,
+            NETWORK_TYPE_CDMA,
+            NETWORK_TYPE_EVDO_0,
+            NETWORK_TYPE_EVDO_A,
+            NETWORK_TYPE_1xRTT,
+            NETWORK_TYPE_HSDPA,
+            NETWORK_TYPE_HSUPA,
+            NETWORK_TYPE_HSPA,
+            NETWORK_TYPE_IDEN,
+            NETWORK_TYPE_EVDO_B,
+            NETWORK_TYPE_LTE,
+            NETWORK_TYPE_EHRPD,
+            NETWORK_TYPE_HSPAP,
+            NETWORK_TYPE_GSM,
+            NETWORK_TYPE_TD_SCDMA,
+            NETWORK_TYPE_IWLAN,
+            NETWORK_TYPE_LTE_CA,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NetworkType{}
+
     /**
      * @return the NETWORK_TYPE_xxxx for current data connection.
      */
-    public int getNetworkType() {
+    public @NetworkType int getNetworkType() {
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
@@ -2138,24 +2176,24 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-   @UnsupportedAppUsage
-   public int getNetworkType(int subId) {
-       try {
-           ITelephony telephony = getITelephony();
-           if (telephony != null) {
-               return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName());
-           } else {
-               // This can happen when the ITelephony interface is not up yet.
-               return NETWORK_TYPE_UNKNOWN;
-           }
-       } catch(RemoteException ex) {
-           // This shouldn't happen in the normal case
-           return NETWORK_TYPE_UNKNOWN;
-       } catch (NullPointerException ex) {
-           // This could happen before phone restarts due to crashing
-           return NETWORK_TYPE_UNKNOWN;
-       }
-   }
+    @UnsupportedAppUsage
+    public int getNetworkType(int subId) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName());
+            } else {
+                // This can happen when the ITelephony interface is not up yet.
+                return NETWORK_TYPE_UNKNOWN;
+            }
+        } catch (RemoteException ex) {
+            // This shouldn't happen in the normal case
+            return NETWORK_TYPE_UNKNOWN;
+        } catch (NullPointerException ex) {
+            // This could happen before phone restarts due to crashing
+            return NETWORK_TYPE_UNKNOWN;
+        }
+    }
 
     /**
      * Returns a constant indicating the radio technology (network type)
@@ -2188,7 +2226,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public int getDataNetworkType() {
+    public @NetworkType int getDataNetworkType() {
         return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
     }
 
@@ -2228,7 +2266,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public int getVoiceNetworkType() {
+    public @NetworkType int getVoiceNetworkType() {
         return getVoiceNetworkType(getSubId());
     }
 
@@ -2885,7 +2923,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}
@@ -4107,11 +4145,16 @@
     }
 
     /**
-     * Returns the IMS home network domain name that was loaded from the ISIM.
-     * @return the IMS domain name, or null if not present or not loaded
+     * Returns the IMS home network domain name that was loaded from the ISIM {@see #APPTYPE_ISIM}.
+     * @return the IMS domain name. Returns {@code null} if ISIM hasn't been loaded or IMS domain
+     * hasn't been loaded or isn't present on the ISIM.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getIsimDomain() {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -4339,15 +4382,15 @@
     * @hide
     */
     private ITelecomService getTelecomService() {
-        return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
+        return ITelecomService.Stub.asInterface(ServiceManager.getService(TELECOM_SERVICE));
     }
 
     private ITelephonyRegistry getTelephonyRegistry() {
         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"));
     }
 
     //
@@ -5369,7 +5412,19 @@
         }
     }
 
-    // ICC SIM Application Types
+    /**
+     * UICC SIM Application Types
+     * @hide
+     */
+    @IntDef(prefix = { "APPTYPE_" }, value = {
+            APPTYPE_SIM,
+            APPTYPE_USIM,
+            APPTYPE_RUIM,
+            APPTYPE_CSIM,
+            APPTYPE_ISIM
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UiccAppType{}
     /** UICC application type is SIM */
     public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM;
     /** UICC application type is USIM */
@@ -5380,6 +5435,7 @@
     public static final int APPTYPE_CSIM = PhoneConstants.APPTYPE_CSIM;
     /** UICC application type is ISIM */
     public static final int APPTYPE_ISIM = PhoneConstants.APPTYPE_ISIM;
+
     // authContext (parameter P2) when doing UICC challenge,
     // per 3GPP TS 31.102 (Section 7.1.2)
     /** Authentication type for UICC challenge is EAP SIM. See RFC 4186 for details. */
@@ -5646,6 +5702,202 @@
         }
     }
 
+    /** @hide */
+    @IntDef(prefix = { "NETWORK_MODE_" }, value = {
+            NETWORK_MODE_WCDMA_PREF,
+            NETWORK_MODE_GSM_ONLY,
+            NETWORK_MODE_WCDMA_ONLY,
+            NETWORK_MODE_GSM_UMTS,
+            NETWORK_MODE_CDMA_EVDO,
+            NETWORK_MODE_CDMA_NO_EVDO,
+            NETWORK_MODE_EVDO_NO_CDMA,
+            NETWORK_MODE_GLOBAL,
+            NETWORK_MODE_LTE_CDMA_EVDO,
+            NETWORK_MODE_LTE_GSM_WCDMA,
+            NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA,
+            NETWORK_MODE_LTE_ONLY,
+            NETWORK_MODE_LTE_WCDMA,
+            NETWORK_MODE_TDSCDMA_ONLY,
+            NETWORK_MODE_TDSCDMA_WCDMA,
+            NETWORK_MODE_LTE_TDSCDMA,
+            NETWORK_MODE_TDSCDMA_GSM,
+            NETWORK_MODE_LTE_TDSCDMA_GSM,
+            NETWORK_MODE_TDSCDMA_GSM_WCDMA,
+            NETWORK_MODE_LTE_TDSCDMA_WCDMA,
+            NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA,
+            NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA,
+            NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PrefNetworkMode{}
+
+    /**
+     * preferred network mode is GSM/WCDMA (WCDMA preferred).
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF;
+
+    /**
+     * preferred network mode is GSM only.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY;
+
+    /**
+     * preferred network mode is WCDMA only.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY;
+
+    /**
+     * preferred network mode is GSM/WCDMA (auto mode, according to PRL).
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS;
+
+    /**
+     * preferred network mode is CDMA and EvDo (auto mode, according to PRL).
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA;
+
+    /**
+     * preferred network mode is CDMA only.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
+
+    /**
+     * preferred network mode is EvDo only.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
+
+    /**
+     * preferred network mode is GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL).
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL;
+
+    /**
+     * preferred network mode is LTE, CDMA and EvDo.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
+
+    /**
+     * preferred network mode is LTE, GSM/WCDMA.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA;
+
+    /**
+     * preferred network mode is LTE, CDMA, EvDo, GSM/WCDMA.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA =
+            RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+
+    /**
+     * preferred network mode is LTE Only.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY;
+
+    /**
+     * preferred network mode is LTE/WCDMA.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_WCDMA = RILConstants.NETWORK_MODE_LTE_WCDMA;
+
+    /**
+     * preferred network mode is TD-SCDMA only.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_TDSCDMA_ONLY = RILConstants.NETWORK_MODE_TDSCDMA_ONLY;
+
+    /**
+     * preferred network mode is TD-SCDMA and WCDMA.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA;
+
+    /**
+     * preferred network mode is TD-SCDMA and LTE.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_TDSCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA;
+
+    /**
+     * preferred network mode is TD-SCDMA and GSM.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_TDSCDMA_GSM;
+
+    /**
+     * preferred network mode is TD-SCDMA,GSM and LTE.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_TDSCDMA_GSM =
+            RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
+
+    /**
+     * preferred network mode is TD-SCDMA, GSM/WCDMA.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA =
+            RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
+
+    /**
+     * preferred network mode is TD-SCDMA, WCDMA and LTE.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA =
+            RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
+
+    /**
+     * preferred network mode is TD-SCDMA, GSM/WCDMA and LTE.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA =
+            RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
+
+    /**
+     * preferred network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
+            RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+    /**
+     * preferred network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo.
+     * @hide
+     */
+    @SystemApi
+    public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
+            RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+
     /**
      * Get the preferred network type.
      * Used for device configuration by some CDMA operators.
@@ -5654,11 +5906,12 @@
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
-     * @return the preferred network type, defined in RILConstants.java.
+     * @return the preferred network type.
      * @hide
      */
-    @UnsupportedAppUsage
-    public int getPreferredNetworkType(int subId) {
+    @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
+    @SystemApi
+    public @PrefNetworkMode int getPreferredNetworkType(int subId) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
@@ -5675,7 +5928,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
@@ -5700,7 +5953,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.
      *
@@ -5779,7 +6032,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
@@ -5789,21 +6042,46 @@
      * @param persistSelection whether the selection will persist until reboot. If true, only allows
      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
      * normal network selection next time.
-     * @return true on success; false on any failure.
+     * @return {@code true} on success; {@code false} on any failure.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setNetworkSelectionModeManual(String operatorNumeric, boolean persistSelection) {
+        return setNetworkSelectionModeManual(
+                new OperatorInfo(
+                        "" /* operatorAlphaLong */, "" /* operatorAlphaShort */, operatorNumeric),
+                persistSelection);
+    }
+
+    /**
+     * 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#getDefaultSubscriptionId()}
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+     * app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @param operatorInfo included the PLMN id, long name, short name of the operator to attach to.
+     * @param persistSelection whether the selection will persist until reboot. If true, only allows
+     * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
+     * normal network selection next time.
+     * @return {@code true} on success; {@code true} on any failure.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setNetworkSelectionModeManual(
+            OperatorInfo operatorInfo, boolean persistSelection) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 return telephony.setNetworkSelectionModeManual(
-                        getSubId(), operatorNumeric, persistSelection);
+                        getSubId(), operatorInfo, persistSelection);
             }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "setNetworkSelectionModeManual RemoteException", ex);
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "setNetworkSelectionModeManual NPE", ex);
         }
         return false;
     }
@@ -5812,7 +6090,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.
      *
@@ -6215,57 +6493,42 @@
     }
 
     /**
-     * @deprecated Use {@link android.telecom.TelecomManager#endCall()} instead.
+     * @removed Use {@link android.telecom.TelecomManager#endCall()} instead.
      * @hide
+     * @removed
      */
     @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.CALL_PHONE)
     public boolean endCall() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.endCall();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#endCall", e);
-        }
         return false;
     }
 
     /**
-     * @deprecated Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
+     * @removed Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
      * @hide
+     * @removed
      */
     @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void answerRingingCall() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                telephony.answerRingingCall();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
-        }
+        // No-op
     }
 
     /**
-     * @deprecated Use {@link android.telecom.TelecomManager#silenceRinger} instead
+     * @removed Use {@link android.telecom.TelecomManager#silenceRinger} instead
      * @hide
      */
     @Deprecated
     @SystemApi
     @SuppressLint("Doclava125")
     public void silenceRinger() {
-        try {
-            getTelecomService().silenceRinger(getOpPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
-        }
+        // No-op
     }
 
     /**
-     * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead
+     * @removed Use {@link android.telecom.TelecomManager#isInCall} instead
      * @hide
      */
     @Deprecated
@@ -6275,18 +6538,11 @@
             android.Manifest.permission.READ_PHONE_STATE
     })
     public boolean isOffhook() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.isOffhook(getOpPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#isOffhook", e);
-        }
         return false;
     }
 
     /**
-     * @deprecated Use {@link android.telecom.TelecomManager#isRinging} instead
+     * @removed Use {@link android.telecom.TelecomManager#isRinging} instead
      * @hide
      */
     @Deprecated
@@ -6296,18 +6552,11 @@
             android.Manifest.permission.READ_PHONE_STATE
     })
     public boolean isRinging() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.isRinging(getOpPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#isRinging", e);
-        }
         return false;
     }
 
     /**
-     * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead
+     * @removed Use {@link android.telecom.TelecomManager#isInCall} instead
      * @hide
      */
     @Deprecated
@@ -6317,13 +6566,6 @@
             android.Manifest.permission.READ_PHONE_STATE
     })
     public boolean isIdle() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.isIdle(getOpPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#isIdle", e);
-        }
         return true;
     }
 
@@ -6738,7 +6980,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);
@@ -6750,7 +6993,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}.
@@ -6775,7 +7018,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},
@@ -6844,7 +7087,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);
@@ -7637,7 +7881,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}).
@@ -7809,26 +8053,23 @@
     }
 
     /**
-     * Return the application ID for the app type like {@link APPTYPE_CSIM}.
+     * Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}.
+     * All uicc applications are uniquely identified by application ID. See ETSI 102.221 and 101.220
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
      *
-     * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
-     *
-     * @param appType the uicc app type like {@link APPTYPE_CSIM}
-     * @return Application ID for specificied app type or null if no uicc or error.
+     * @param appType the uicc app type.
+     * @return Application ID for specified app type or {@code null} if no uicc or error.
      * @hide
      */
-    public String getAidForAppType(int appType) {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public String getAidForAppType(@UiccAppType int appType) {
         return getAidForAppType(getSubId(), appType);
     }
 
     /**
-     * Return the application ID for the app type like {@link APPTYPE_CSIM}.
-     *
-     * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
-     *
-     * @param subId the subscription ID that this request applies to.
-     * @param appType the uicc app type, like {@link APPTYPE_CSIM}
-     * @return Application ID for specificied app type or null if no uicc or error.
+     * same as {@link #getAidForAppType(int)}
      * @hide
      */
     public String getAidForAppType(int subId, int appType) {
@@ -8109,7 +8350,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
@@ -8140,6 +8381,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
@@ -8338,10 +8602,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:
@@ -8352,25 +8616,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>
@@ -8379,17 +8643,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..8379f8c 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -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/emergency/EmergencyNumber.aidl b/telephony/java/android/telephony/emergency/EmergencyNumber.aidl
new file mode 100644
index 0000000..bfb0a59
--- /dev/null
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+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..d6a08543
--- /dev/null
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 {
+
+    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 {@link EmergencyServiceCategories} of
+     * the emergency number.
+     *
+     * @return bitmask of the emergency service categories {@link EmergencyServiceCategories}
+     */
+    public @EmergencyServiceCategories int getEmergencyServiceCategoryBitmask() {
+        return mEmergencyServiceCategoryBitmask;
+    }
+
+    /**
+     * Returns the emergency service categories {@link EmergencyServiceCategories} of the emergency
+     * number.
+     *
+     * @return a list of the emergency service categories {@link EmergencyServiceCategories}
+     */
+    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 specified emergency service category(s)
+     * {@link EmergencyServiceCategories}.
+     *
+     * @return {@code true} if the emergency number is in the specified emergency service
+     * category(s) {@link EmergencyServiceCategories}; {@code false} otherwise.
+     *
+     * @param categories - emergency service categories {@link EmergencyServiceCategories}
+     */
+    public boolean isInEmergencyServiceCategories(@EmergencyServiceCategories int categories) {
+        if (categories == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED) {
+            return serviceUnspecified();
+        }
+        return (mEmergencyServiceCategoryBitmask & categories) == categories;
+    }
+
+    /**
+     * Returns the bitmask of the sources {@link EmergencyNumberSources} of the emergency number.
+     *
+     * @return bitmask of the emergency number sources {@link EmergencyNumberSources}
+     */
+    public @EmergencyNumberSources int getEmergencyNumberSourceBitmask() {
+        return mEmergencyNumberSourceBitmask;
+    }
+
+    /**
+     * Returns a list of {@link EmergencyNumberSources} of the emergency number.
+     *
+     * @return a list of {@link EmergencyNumberSources}
+     */
+    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)
+     * {@link EmergencyNumberSources}.
+     *
+     * @return {@code true} if the emergency number is from the specified emergency number
+     * source(s) {@link EmergencyNumberSources}; {@code false} otherwise.
+     *
+     * @param sources - {@link EmergencyNumberSources}
+     */
+    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()));
+    }
+
+    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 f0d3c89..89ef339 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -117,10 +117,14 @@
      * @hide
      */
     public static final String EXTRA_CONFERENCE = "conference";
+
     /**
-     * @hide
+     * 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
      */
@@ -245,7 +249,8 @@
      * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
      * "14" vs (int) 14).
      * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
-     *      updateWifiStateFromExtras(Bundle)} to determine whether to set the
+     *      updateImsCallRatFromExtras(Bundle)} to determine whether to set the
+     * {@link android.telecom.TelecomManager#EXTRA_CALL_NETWORK_TYPE} extra value and
      * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
      */
     public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
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/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 3138180..cecf2e2 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;
@@ -81,13 +80,14 @@
      * Callback class for receiving Registration callback events.
      * @hide
      */
-    public static class Callback {
+    public static class Callback extends IImsRegistrationCallback.Stub {
         /**
          * 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}.
          */
+        @Override
         public void onRegistered(@ImsRegistrationTech int imsRadioTech) {
         }
 
@@ -97,6 +97,7 @@
          * @param imsRadioTech the radio access technology. Valid values are defined in
          * {@link ImsRegistrationTech}.
          */
+        @Override
         public void onRegistering(@ImsRegistrationTech int imsRadioTech) {
         }
 
@@ -105,6 +106,7 @@
          *
          * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
          */
+        @Override
         public void onDeregistered(ImsReasonInfo info) {
         }
 
@@ -115,6 +117,7 @@
          * @param imsRadioTech The {@link ImsRegistrationTech} type that has failed
          * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
          */
+        @Override
         public void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
                 ImsReasonInfo info) {
         }
@@ -125,6 +128,7 @@
          * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
          *         subscription.
          */
+        @Override
         public void onSubscriberAssociatedUriChanged(Uri[] uris) {
 
         }
diff --git a/telephony/java/android/telephony/mbms/GroupCall.java b/telephony/java/android/telephony/mbms/GroupCall.java
new file mode 100644
index 0000000..9aca18e
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/GroupCall.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mbms;
+
+import android.annotation.IntDef;
+import android.os.RemoteException;
+import android.telephony.MbmsGroupCallSession;
+import android.telephony.mbms.vendor.IMbmsGroupCallService;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Class used to represent a single MBMS group call. After a call has been started with
+ * {@link MbmsGroupCallSession#startGroupCall},
+ * this class is used to hold information about the call and control it.
+ */
+public class GroupCall implements AutoCloseable {
+    private static final String LOG_TAG = "MbmsGroupCall";
+
+    /**
+     * The state of a group call, reported via
+     * {@link GroupCallCallback#onGroupCallStateChanged(int, int)}
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "STATE_" }, value = {STATE_STOPPED, STATE_STARTED, STATE_STALLED})
+    public @interface GroupCallState {}
+    public static final int STATE_STOPPED = 1;
+    public static final int STATE_STARTED = 2;
+    public static final int STATE_STALLED = 3;
+
+    /**
+     * The reason for a call state change, reported via
+     * {@link GroupCallCallback#onGroupCallStateChanged(int, int)}
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "REASON_" },
+            value = {REASON_BY_USER_REQUEST, REASON_FREQUENCY_CONFLICT,
+                    REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE,
+                    REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE})
+    public @interface GroupCallStateChangeReason {}
+
+    /**
+     * Indicates that the middleware does not have a reason to provide for the state change.
+     */
+    public static final int REASON_NONE = 0;
+
+    /**
+     * State changed due to a call to {@link #close()} or
+     * {@link MbmsGroupCallSession#startGroupCall}
+     */
+    public static final int REASON_BY_USER_REQUEST = 1;
+
+    // 2 is unused to match up with streaming.
+
+    /**
+     * State changed due to a frequency conflict with another requested call.
+     */
+    public static final int REASON_FREQUENCY_CONFLICT = 3;
+
+    /**
+     * State changed due to the middleware running out of memory
+     */
+    public static final int REASON_OUT_OF_MEMORY = 4;
+
+    /**
+     * State changed due to the device leaving the home carrier's LTE network.
+     */
+    public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5;
+
+    /**
+     * State changed due to the device leaving the area where this call is being broadcast.
+     */
+    public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6;
+
+    private final int mSubscriptionId;
+    private final long mTmgi;
+    private final MbmsGroupCallSession mParentSession;
+    private final InternalGroupCallCallback mCallback;
+    private IMbmsGroupCallService mService;
+
+    /**
+     * @hide
+     */
+    public GroupCall(int subscriptionId,
+            IMbmsGroupCallService service,
+            MbmsGroupCallSession session,
+            long tmgi,
+            InternalGroupCallCallback callback) {
+        mSubscriptionId = subscriptionId;
+        mParentSession = session;
+        mService = service;
+        mTmgi = tmgi;
+        mCallback = callback;
+    }
+
+    /**
+     * Retrieve the TMGI (Temporary Mobile Group Identity) corresponding to this call.
+     */
+    public long getTmgi() {
+        return mTmgi;
+    }
+
+    /**
+     * Send an update to the middleware when the SAI (Service Area Identifier) list and frequency
+     * information of the group call has * changed. Callers must obtain this information from the
+     * wireless carrier independently.
+     * @param saiArray New array of SAIs that the call is available on.
+     * @param frequencyArray New array of frequencies that the call is available on.
+     */
+    public void updateGroupCall(int[] saiArray, int[] frequencyArray) {
+        if (mService == null) {
+            throw new IllegalStateException("No group call service attached");
+        }
+
+        try {
+            mService.updateGroupCall(mSubscriptionId, mTmgi, saiArray, frequencyArray);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        } finally {
+            mParentSession.onGroupCallStopped(this);
+        }
+    }
+
+    /**
+     * Stop this group call. Further operations on this object will fail with an
+     * {@link IllegalStateException}.
+     *
+     * May throw an {@link IllegalStateException}
+     */
+    @Override
+    public void close() {
+        if (mService == null) {
+            throw new IllegalStateException("No group call service attached");
+        }
+
+        try {
+            mService.stopGroupCall(mSubscriptionId, mTmgi);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+        } finally {
+            mParentSession.onGroupCallStopped(this);
+        }
+    }
+
+    /** @hide */
+    public InternalGroupCallCallback getCallback() {
+        return mCallback;
+    }
+
+    private void sendErrorToApp(int errorCode, String message) {
+        mCallback.onError(errorCode, message);
+    }
+}
+
diff --git a/telephony/java/android/telephony/mbms/GroupCallCallback.java b/telephony/java/android/telephony/mbms/GroupCallCallback.java
new file mode 100644
index 0000000..001bb02
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.mbms;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A callback class for use when the application is in a group call. The middleware
+ * will provide updates on the status of the call via this callback.
+ */
+public class GroupCallCallback {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE,
+            MbmsErrors.ERROR_MIDDLEWARE_LOST,
+            MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND,
+            MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
+            MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY,
+            MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
+            MbmsErrors.GeneralErrors.ERROR_IN_E911,
+            MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
+            MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
+            MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" })
+    private @interface GroupCallError{}
+
+    /**
+     * Indicates broadcast signal strength is not available for this call.
+     *
+     * This may be due to the call no longer being available due to geography
+     * or timing (end of service)
+     */
+    public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1;
+
+    /**
+     * Called by the middleware when it has detected an error condition in this group call. The
+     * possible error codes are listed in {@link MbmsErrors}.
+     * @param errorCode The error code.
+     * @param message A human-readable message generated by the middleware for debugging purposes.
+     */
+    public void onError(@GroupCallError int errorCode, @Nullable String message) {
+        // default implementation empty
+    }
+
+    /**
+     * Called to indicate this call has changed state.
+     *
+     * See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED}
+     * and {@link GroupCall#STATE_STALLED}.
+     */
+    public void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
+            @GroupCall.GroupCallStateChangeReason int reason) {
+        // default implementation empty
+    }
+
+    /**
+     * Broadcast Signal Strength updated.
+     *
+     * This signal strength is the BROADCAST signal strength which,
+     * depending on technology in play and it's deployment, may be
+     * stronger or weaker than the traditional UNICAST signal
+     * strength.  It a simple int from 0-4 for valid levels or
+     * {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available
+     * for this call due to timing, geography or popularity.
+     */
+    public void onBroadcastSignalStrengthUpdated(int signalStrength) {
+        // default implementation empty
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl
new file mode 100755
index 0000000..844b634
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl
@@ -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.
+ */
+
+package android.telephony.mbms;
+
+/**
+ * @hide
+ */
+oneway interface IGroupCallCallback {
+    void onError(int errorCode, String message);
+    void onGroupCallStateChanged(int state, int reason);
+    void onBroadcastSignalStrengthUpdated(int signalStrength);
+}
diff --git a/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl
new file mode 100755
index 0000000..1a1c7f8
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl
@@ -0,0 +1,33 @@
+/*
+** 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.telephony.mbms;
+
+import java.util.List;
+
+/**
+ * @hide
+ */
+oneway interface IMbmsGroupCallSessionCallback
+{
+    void onError(int errorCode, String message);
+
+    void onAvailableSaisUpdated(in List currentSai, in List availableSais);
+
+    void onServiceInterfaceAvailable(String interfaceName, int index);
+
+    void onMiddlewareReady();
+}
diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java
new file mode 100644
index 0000000..2910bb3
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.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 android.telephony.mbms;
+
+import android.os.Binder;
+
+import java.util.concurrent.Executor;
+
+/** @hide */
+public class InternalGroupCallCallback extends IGroupCallCallback.Stub {
+    private final GroupCallCallback mAppCallback;
+    private final Executor mExecutor;
+    private volatile boolean mIsStopped = false;
+
+    public InternalGroupCallCallback(GroupCallCallback appCallback,
+            Executor executor) {
+        mAppCallback = appCallback;
+        mExecutor = executor;
+    }
+
+    @Override
+    public void onError(final int errorCode, final String message) {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onError(errorCode, message);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onGroupCallStateChanged(final int state, final int reason) {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onGroupCallStateChanged(state, reason);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onBroadcastSignalStrengthUpdated(final int signalStrength) {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onBroadcastSignalStrengthUpdated(signalStrength);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    /** Prevents this callback from calling the app */
+    public void stop() {
+        mIsStopped = true;
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java
new file mode 100644
index 0000000..4c9cf4d
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.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 android.telephony.mbms;
+
+import android.os.Binder;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/** @hide */
+public class InternalGroupCallSessionCallback extends IMbmsGroupCallSessionCallback.Stub {
+    private final Executor mExecutor;
+    private final MbmsGroupCallSessionCallback mAppCallback;
+    private volatile boolean mIsStopped = false;
+
+    public InternalGroupCallSessionCallback(MbmsGroupCallSessionCallback appCallback,
+            Executor executor) {
+        mAppCallback = appCallback;
+        mExecutor = executor;
+    }
+
+    @Override
+    public void onError(final int errorCode, final String message) {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onError(errorCode, message);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onAvailableSaisUpdated(final List currentSais, final List availableSais) {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onAvailableSaisUpdated(currentSais, availableSais);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onServiceInterfaceAvailable(final String interfaceName, final int index) {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onServiceInterfaceAvailable(interfaceName, index);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onMiddlewareReady() {
+        if (mIsStopped) {
+            return;
+        }
+
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onMiddlewareReady();
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        });
+    }
+
+    /** Prevents this callback from calling the app */
+    public void stop() {
+        mIsStopped = true;
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
new file mode 100644
index 0000000..7da734e
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mbms;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.telephony.MbmsGroupCallSession;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * A callback class that is used to receive information from the middleware on MBMS group-call
+ * services. An instance of this object should be passed into
+ * {@link MbmsGroupCallSession#create(Context, Executor, int, MbmsGroupCallSessionCallback)}.
+ */
+public class MbmsGroupCallSessionCallback {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE,
+            MbmsErrors.ERROR_MIDDLEWARE_LOST,
+            MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND,
+            MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED,
+            MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE,
+            MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+            MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
+            MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY,
+            MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
+            MbmsErrors.GeneralErrors.ERROR_IN_E911,
+            MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
+            MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
+            MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" })
+    private @interface GroupCallError{}
+
+    /**
+     * Called by the middleware when it has detected an error condition. The possible error codes
+     * are listed in {@link MbmsErrors}.
+     * @param errorCode The error code.
+     * @param message A human-readable message generated by the middleware for debugging purposes.
+     */
+    public void onError(@GroupCallError int errorCode, @Nullable String message) {
+    }
+
+    /**
+     * Indicates that the list of currently available SAIs has been updated. The app may use this
+     * information to filter the list of group calls when displaying available group calls to
+     * the user by matching the SAIs with a list of group calls separately negotiated with the
+     * carrier. The app may also report the aggregate list of SAIs to the group call application
+     * server so that a network entity can determine when, and where to activate the broadcast of
+     * particular group calls.
+     * @param currentSais The available SAIs on the current cell.
+     * @param availableSais A list of lists of available SAIS in neighboring cells, where each list
+     *                      contains the available SAIs in an individual cell.
+     */
+    public void onAvailableSaisUpdated(List<Integer> currentSais,
+            List<List<Integer>> availableSais) {
+    }
+
+    /**
+     * Called soon after the app calls {@link MbmsGroupCallSession#create}. The information supplied
+     * via this callback may be used to establish a data-link interface with the modem before the
+     * middleware is ready.
+     * Note that this method may be called before {@link #onMiddlewareReady()}.
+     *
+     * @param interfaceName The interface name for the data link.
+     * @param index The index for the data link.
+     */
+    public void onServiceInterfaceAvailable(String interfaceName, int index) {
+    }
+
+    /**
+     * Called to indicate that the middleware has been initialized and is ready.
+     *
+     * Before this method is called, calling any method on an instance of
+     * {@link MbmsGroupCallSession} will result in an {@link IllegalStateException} or an error
+     * delivered via {@link #onError(int, String)} with error code
+     * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}.
+     */
+    public void onMiddlewareReady() {
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java
index 06b2120..95b4d37 100644
--- a/telephony/java/android/telephony/mbms/MbmsUtils.java
+++ b/telephony/java/android/telephony/mbms/MbmsUtils.java
@@ -23,6 +23,7 @@
 import android.content.pm.*;
 import android.content.pm.ServiceInfo;
 import android.telephony.MbmsDownloadSession;
+import android.telephony.MbmsGroupCallSession;
 import android.telephony.MbmsStreamingSession;
 import android.util.Log;
 
@@ -59,6 +60,9 @@
             case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION:
                 metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA;
                 break;
+            case MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_ACTION:
+                metaDataKey = MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA;
+                break;
         }
         if (metaDataKey == null) {
             return null;
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl
new file mode 100755
index 0000000..721256a
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl
@@ -0,0 +1,39 @@
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony.mbms.vendor;
+
+import android.net.Uri;
+import android.telephony.mbms.IMbmsGroupCallSessionCallback;
+import android.telephony.mbms.IGroupCallCallback;
+
+/**
+ * @hide
+ */
+interface IMbmsGroupCallService
+{
+    int initialize(IMbmsGroupCallSessionCallback callback, int subId);
+
+    void stopGroupCall(int subId, long tmgi);
+
+    void updateGroupCall(int subscriptionId, long tmgi, in int[] saiArray,
+        in int[] frequencyArray);
+
+    int startGroupCall(int subscriptionId, long tmgi, in int[] saiArray,
+        in int[] frequencyArray, IGroupCallCallback callback);
+
+    void dispose(int subId);
+}
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
new file mode 100644
index 0000000..3734ca7
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mbms.vendor;
+
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.mbms.GroupCallCallback;
+import android.telephony.mbms.IGroupCallCallback;
+import android.telephony.mbms.IMbmsGroupCallSessionCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsGroupCallSessionCallback;
+import android.telephony.mbms.vendor.IMbmsGroupCallService.Stub;
+
+import java.util.List;
+
+/**
+ * Base class for MBMS group-call services. The middleware should override this class to implement
+ * its {@link Service} for group calls
+ * Subclasses should call this class's {@link #onBind} method to obtain an {@link IBinder} if they
+ * override {@link #onBind}.
+ * @hide
+ */
+@SystemApi
+@TestApi
+public class MbmsGroupCallServiceBase extends Service {
+    private final IBinder mInterface = new Stub() {
+        @Override
+        public int initialize(final IMbmsGroupCallSessionCallback callback,
+                final int subscriptionId) throws RemoteException {
+            if (callback == null) {
+                throw new NullPointerException("Callback must not be null");
+            }
+
+            final int uid = Binder.getCallingUid();
+
+            int result = MbmsGroupCallServiceBase.this.initialize(
+                    new MbmsGroupCallSessionCallback() {
+                        @Override
+                        public void onError(final int errorCode, final String message) {
+                            try {
+                                if (errorCode == MbmsErrors.UNKNOWN) {
+                                    throw new IllegalArgumentException(
+                                            "Middleware cannot send an unknown error.");
+                                }
+                                callback.onError(errorCode, message);
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+
+                        @Override
+                        public void onAvailableSaisUpdated(final List currentSais,
+                                final List availableSais) {
+                            try {
+                                callback.onAvailableSaisUpdated(currentSais, availableSais);
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+
+                        @Override
+                        public void onServiceInterfaceAvailable(final String interfaceName,
+                                final int index) {
+                            try {
+                                callback.onServiceInterfaceAvailable(interfaceName, index);
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+
+                        @Override
+                        public void onMiddlewareReady() {
+                            try {
+                                callback.onMiddlewareReady();
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+                    }, subscriptionId);
+
+            if (result == MbmsErrors.SUCCESS) {
+                callback.asBinder().linkToDeath(new DeathRecipient() {
+                    @Override
+                    public void binderDied() {
+                        onAppCallbackDied(uid, subscriptionId);
+                    }
+                }, 0);
+            }
+
+            return result;
+        }
+
+        @Override
+        public void stopGroupCall(int subId, long tmgi) {
+            MbmsGroupCallServiceBase.this.stopGroupCall(subId, tmgi);
+        }
+
+        @Override
+        public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray,
+                int[] frequencyArray) {
+            MbmsGroupCallServiceBase.this.updateGroupCall(
+                    subscriptionId, tmgi, saiArray, frequencyArray);
+        }
+
+        @Override
+        public int startGroupCall(final int subscriptionId, final long tmgi, final int[] saiArray,
+                final int[] frequencyArray, final IGroupCallCallback callback)
+                throws RemoteException {
+            if (callback == null) {
+                throw new NullPointerException("Callback must not be null");
+            }
+
+            final int uid = Binder.getCallingUid();
+
+            int result = MbmsGroupCallServiceBase.this.startGroupCall(
+                    subscriptionId, tmgi, saiArray, frequencyArray, new GroupCallCallback() {
+                        @Override
+                        public void onError(final int errorCode, final String message) {
+                            try {
+                                if (errorCode == MbmsErrors.UNKNOWN) {
+                                    throw new IllegalArgumentException(
+                                            "Middleware cannot send an unknown error.");
+                                }
+                                callback.onError(errorCode, message);
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+
+                        public void onGroupCallStateChanged(int state, int reason) {
+                            try {
+                                callback.onGroupCallStateChanged(state, reason);
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+
+                        public void onBroadcastSignalStrengthUpdated(int signalStrength) {
+                            try {
+                                callback.onBroadcastSignalStrengthUpdated(signalStrength);
+                            } catch (RemoteException e) {
+                                onAppCallbackDied(uid, subscriptionId);
+                            }
+                        }
+                    });
+
+            if (result == MbmsErrors.SUCCESS) {
+                callback.asBinder().linkToDeath(new DeathRecipient() {
+                    @Override
+                    public void binderDied() {
+                        onAppCallbackDied(uid, subscriptionId);
+                    }
+                }, 0);
+            }
+
+            return result;
+        }
+
+        @Override
+        public void dispose(int subId) throws RemoteException {
+            MbmsGroupCallServiceBase.this.dispose(subId);
+        }
+    };
+
+    /**
+     * Initialize the group call service for this app and subscription ID, registering the callback.
+     *
+     * May throw an {@link IllegalArgumentException} or a {@link SecurityException}, which
+     * will be intercepted and passed to the app as
+     * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
+     *
+     * May return any value from {@link MbmsErrors.InitializationErrors}
+     * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via
+     * {@link IMbmsGroupCallSessionCallback#onError(int, String)}.
+     *
+     * @param callback The callback to use to communicate with the app.
+     * @param subscriptionId The subscription ID to use.
+     */
+    public int initialize(MbmsGroupCallSessionCallback callback, int subscriptionId)
+            throws RemoteException {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    /**
+     * Starts a particular group call. This method may perform asynchronous work. When
+     * the call is ready for consumption, the middleware should inform the app via
+     * {@link IGroupCallCallback#onGroupCallStateChanged(int, int)}.
+     *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     *
+     * @param subscriptionId The subscription id to use.
+     * @param tmgi The TMGI, an identifier for the group call.
+     * @param saiArray An array of SAIs for the group call.
+     * @param frequencyArray An array of frequencies for the group call.
+     * @param callback The callback object on which the app wishes to receive updates.
+     * @return Any error in {@link MbmsErrors.GeneralErrors}
+     */
+    public int startGroupCall(int subscriptionId, long tmgi, int[] saiArray, int[] frequencyArray,
+            GroupCallCallback callback) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    /**
+     * Stop the group call identified by {@code tmgi}.
+     *
+     * The callback provided via {@link #startGroupCall} should no longer be
+     * used after this method has called by the app.
+     *
+     * May throw an {@link IllegalStateException}
+     *
+     * @param subscriptionId The subscription id to use.
+     * @param tmgi The TMGI for the call to stop.
+     */
+    public void stopGroupCall(int subscriptionId, long tmgi) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    /**
+     * Called when the app receives new SAI and frequency information for the group call identified
+     * by {@code tmgi}.
+     * @param saiArray New array of SAIs that the call is available on.
+     * @param frequencyArray New array of frequencies that the call is available on.
+     */
+    public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray,
+            int[] frequencyArray) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    /**
+     * Signals that the app wishes to dispose of the session identified by the
+     * {@code subscriptionId} argument and the caller's uid. No notification back to the
+     * app is required for this operation, and the corresponding callback provided via
+     * {@link #initialize} should no longer be used
+     * after this method has been called by the app.
+     *
+     * May throw an {@link IllegalStateException}
+     *
+     * @param subscriptionId The subscription id to use.
+     */
+    public void dispose(int subscriptionId) throws RemoteException {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    /**
+     * Indicates that the app identified by the given UID and subscription ID has died.
+     * @param uid the UID of the app, as returned by {@link Binder#getCallingUid()}.
+     * @param subscriptionId The subscription ID the app is using.
+     */
+    public void onAppCallbackDied(int uid, int subscriptionId) {
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mInterface;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/IAnas.aidl b/telephony/java/com/android/internal/telephony/IAnas.aidl
deleted file mode 100755
index 88d681a..0000000
--- a/telephony/java/com/android/internal/telephony/IAnas.aidl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-
-interface IAnas {
-
-    /**
-    * Enable or disable Alternative Network Access service.
-    *
-    * This method should be called to enable or disable
-    * AlternativeNetworkAccess service on the device.
-    *
-    * <p>
-    * Requires Permission:
-    *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-    * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
-    *
-    * @param enable enable(True) or disable(False)
-    * @param callingPackage caller's package name
-    * @return returns true if successfully set.
-    */
-    boolean setEnable(boolean enable, String callingPackage);
-
-    /**
-     * is Alternative Network Access service enabled
-     *
-     * This method should be called to determine if the Alternative Network Access service is enabled
-    *
-    * <p>
-    * Requires Permission:
-    *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-    * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
-    *
-    * @param callingPackage caller's package name
-    */
-    boolean isEnabled(String callingPackage);
-}
diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl
new file mode 100755
index 0000000..6eb8d66
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IAns.aidl
@@ -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 com.android.internal.telephony;
+
+
+interface IAns {
+
+    /**
+    * Enable or disable Alternative Network service.
+    *
+    * This method should be called to enable or disable
+    * AlternativeNetwork service on the device.
+    *
+    * <p>
+    * Requires Permission:
+    *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+    * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+    *
+    * @param enable enable(True) or disable(False)
+    * @param callingPackage caller's package name
+    * @return returns true if successfully set.
+    */
+    boolean setEnable(boolean enable, String callingPackage);
+
+    /**
+     * is Alternative Network service enabled
+     *
+     * This method should be called to determine if the Alternative Network service is enabled
+    *
+    * <p>
+    * Requires Permission:
+    *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+    * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+    *
+    * @param callingPackage caller's package name
+    */
+    boolean isEnabled(String callingPackage);
+}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 1ebb697..38a1bc7 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -52,5 +52,6 @@
     void onCarrierNetworkChange(in boolean active);
     void onUserMobileDataStateChanged(in boolean enabled);
     void onPhoneCapabilityChanged(in PhoneCapability capability);
+    void onPreferredDataSubIdChanged(in int subId);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 6521f0b..0ccd748 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -232,5 +232,5 @@
      */
     int getSimStateForSlotIndex(int slotIndex);
 
-    boolean isActiveSubId(int subId);
+    boolean isActiveSubId(int subId, String callingPackage);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index c0bccde..32eb12b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -75,116 +75,6 @@
     void call(String callingPackage, String number);
 
     /**
-     * End call if there is a call in progress, otherwise does nothing.
-     *
-     * @return whether it hung up
-     */
-    boolean endCall();
-
-    /**
-     * End call on particular subId or go to the Home screen
-     * @param subId user preferred subId.
-     * @return whether it hung up
-     */
-    boolean endCallForSubscriber(int subId);
-
-    /**
-     * Answer the currently-ringing call.
-     *
-     * If there's already a current active call, that call will be
-     * automatically put on hold.  If both lines are currently in use, the
-     * current active call will be ended.
-     *
-     * TODO: provide a flag to let the caller specify what policy to use
-     * if both lines are in use.  (The current behavior is hardwired to
-     * "answer incoming, end ongoing", which is how the CALL button
-     * is specced to behave.)
-     *
-     * TODO: this should be a oneway call (especially since it's called
-     * directly from the key queue thread).
-     */
-    void answerRingingCall();
-
-    /**
-     * Answer the currently-ringing call on particular subId .
-     *
-     * If there's already a current active call, that call will be
-     * automatically put on hold.  If both lines are currently in use, the
-     * current active call will be ended.
-     *
-     * TODO: provide a flag to let the caller specify what policy to use
-     * if both lines are in use.  (The current behavior is hardwired to
-     * "answer incoming, end ongoing", which is how the CALL button
-     * is specced to behave.)
-     *
-     * TODO: this should be a oneway call (especially since it's called
-     * directly from the key queue thread).
-     */
-    void answerRingingCallForSubscriber(int subId);
-
-    /**
-     * Silence the ringer if an incoming call is currently ringing.
-     * (If vibrating, stop the vibrator also.)
-     *
-     * It's safe to call this if the ringer has already been silenced, or
-     * even if there's no incoming call.  (If so, this method will do nothing.)
-     *
-     * TODO: this should be a oneway call too (see above).
-     *       (Actually *all* the methods here that return void can
-     *       probably be oneway.)
-     */
-    void silenceRinger();
-
-    /**
-     * Check if we are in either an active or holding call
-     * @param callingPackage the name of the package making the call.
-     * @return true if the phone state is OFFHOOK.
-     */
-    boolean isOffhook(String callingPackage);
-
-    /**
-     * Check if a particular subId has an active or holding call
-     *
-     * @param subId user preferred subId.
-     * @param callingPackage the name of the package making the call.
-     * @return true if the phone state is OFFHOOK.
-     */
-    boolean isOffhookForSubscriber(int subId, String callingPackage);
-
-    /**
-     * Check if an incoming phone call is ringing or call waiting
-     * on a particular subId.
-     *
-     * @param subId user preferred subId.
-     * @param callingPackage the name of the package making the call.
-     * @return true if the phone state is RINGING.
-     */
-    boolean isRingingForSubscriber(int subId, String callingPackage);
-
-    /**
-     * Check if an incoming phone call is ringing or call waiting.
-     * @param callingPackage the name of the package making the call.
-     * @return true if the phone state is RINGING.
-     */
-    boolean isRinging(String callingPackage);
-
-    /**
-     * Check if the phone is idle.
-     * @param callingPackage the name of the package making the call.
-     * @return true if the phone state is IDLE.
-     */
-    boolean isIdle(String callingPackage);
-
-    /**
-     * Check if the phone is idle on a particular subId.
-     *
-     * @param subId user preferred subId.
-     * @param callingPackage the name of the package making the call.
-     * @return true if the phone state is IDLE.
-     */
-    boolean isIdleForSubscriber(int subId, String callingPackage);
-
-    /**
      * Check to see if the radio is on or not.
      * @param callingPackage the name of the package making the call.
      * @return returns true if the radio is on.
@@ -865,14 +755,15 @@
      * Ask the radio to connect to the input network and change selection mode to manual.
      *
      * @param subId the id of the subscription.
-     * @param operatorNumeric the PLMN of the operator to attach to.
-     * @param persistSelection Whether the selection will persist until reboot. If true, only allows
+     * @param operatorInfo the operator inforamtion, included the PLMN, long name and short name of
+     * the operator to attach to.
+     * @param persistSelection whether the selection will persist until reboot. If true, only allows
      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
      * normal network selection next time.
-     * @return true if the request suceeded.
+     * @return {@code true} on success; {@code true} on any failure.
      */
-    boolean setNetworkSelectionModeManual(int subId, in String operatorNumeric,
-            boolean persistSelection);
+    boolean setNetworkSelectionModeManual(
+            int subId, in OperatorInfo operatorInfo, boolean persisSelection);
 
     /**
      * Set the preferred network type.
@@ -917,6 +808,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
@@ -1586,4 +1484,19 @@
      * Return the network selection mode on the subscription with id {@code subId}.
      */
      int getNetworkSelectionMode(int subId);
+
+    /**
+     * Get a list of SMS apps on a user.
+     */
+    String[] getSmsApps(int userId);
+
+    /**
+     * Get the default SMS app on a given user.
+     */
+    String getDefaultSmsApp(int userId);
+
+    /**
+     * Set the default SMS app to a given package on a given user.
+     */
+    void setDefaultSmsApp(int userId, String packageName);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 43d56b3..c03065c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -79,4 +79,5 @@
     void notifyCarrierNetworkChange(in boolean active);
     void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state);
     void notifyPhoneCapabilityChanged(in PhoneCapability capability);
+    void notifyPreferredDataSubIdChanged(int preferredSubId);
 }
diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java
index d0245a0..a47e2b0 100644
--- a/telephony/java/com/android/internal/telephony/OperatorInfo.java
+++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java
@@ -21,7 +21,7 @@
 import android.os.Parcelable;
 
 /**
- * {@hide}
+ * @hide
  */
 public class OperatorInfo implements Parcelable {
     public enum State {
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index f9de776..21f3b92 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -176,6 +176,10 @@
 
     // FIXME: This is used to pass a subId via intents, we need to look at its usage, which is
     // FIXME: extensive, and see if this should be an array of all active subId's or ...?
+    /**
+     * @Deprecated use {@link android.telephony.SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}
+     * instead.
+     */
     public static final String SUBSCRIPTION_KEY  = "subscription";
 
     public static final String SUB_SETTING  = "subSettings";
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index d8ef429..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 {
@@ -209,7 +218,14 @@
      * Support smsto Uri scheme.
      */
     public static Collection<SmsApplicationData> getApplicationCollection(Context context) {
-        int userId = getIncomingUserId(context);
+        return getApplicationCollectionAsUser(context, getIncomingUserId(context));
+    }
+
+    /**
+     * Same as {@link #getApplicationCollection} but it takes a target user ID.
+     */
+    public static Collection<SmsApplicationData> getApplicationCollectionAsUser(Context context,
+            int userId) {
         final long token = Binder.clearCallingIdentity();
         try {
             return getApplicationCollectionInternal(context, userId);
@@ -389,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);
                 }
             }
@@ -475,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) {
@@ -530,18 +522,75 @@
         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.
      */
     public static void setDefaultApplication(String packageName, Context context) {
+        setDefaultApplicationAsUser(packageName, context, getIncomingUserId(context));
+    }
+
+    /**
+     * Same as {@link #setDefaultApplication} but takes a target user id.
+     */
+    public static void setDefaultApplicationAsUser(String packageName, Context context,
+            int userId) {
         TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
         if (!tm.isSmsCapable()) {
             // No phone, no SMS
             return;
         }
 
-        final int userId = getIncomingUserId(context);
         final long token = Binder.clearCallingIdentity();
         try {
             setDefaultApplicationInternal(packageName, context, userId);
@@ -552,6 +601,8 @@
 
     private static void setDefaultApplicationInternal(String packageName, Context context,
             int userId) {
+        final UserHandle userHandle = UserHandle.of(userId);
+
         // Get old package name
         String oldPackageName = Settings.Secure.getStringForUser(context.getContentResolver(),
                 Settings.Secure.SMS_DEFAULT_APPLICATION, userId);
@@ -568,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);
                 }
@@ -591,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);
@@ -628,7 +662,7 @@
                 if (DEBUG_MULTIUSER) {
                     Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldAppData.mPackageName);
                 }
-                context.sendBroadcast(oldAppIntent);
+                context.sendBroadcastAsUser(oldAppIntent, userHandle);
             }
             // Notify the new sms app that it's now the default (if the new sms app has a receiver
             // to handle the changed default sms intent).
@@ -646,8 +680,16 @@
                 if (DEBUG_MULTIUSER) {
                     Log.i(LOG_TAG, "setDefaultApplicationInternal new=" + packageName);
                 }
-                context.sendBroadcast(intent);
+                context.sendBroadcastAsUser(intent, userHandle);
             }
+
+            // Send an implicit broadcast for the system server.
+            // (or anyone with MONITOR_DEFAULT_SMS_PACKAGE, really.)
+            final Intent intent =
+                    new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
+            context.sendBroadcastAsUser(intent, userHandle,
+                    permission.MONITOR_DEFAULT_SMS_PACKAGE);
+
             MetricsLogger.action(context, MetricsEvent.ACTION_DEFAULT_SMS_APP_CHANGED,
                     applicationData.mPackageName);
         }
@@ -661,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
@@ -677,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
@@ -687,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);
+        }
     }
 
     /**
@@ -799,7 +852,18 @@
      * @return component name of the app and class to deliver SMS messages to
      */
     public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) {
-        int userId = getIncomingUserId(context);
+        return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId(context));
+    }
+
+    /**
+     * Gets the default SMS application on a given user
+     * @param context context from the calling app
+     * @param updateIfNeeded update the default app if there is no valid default app configured.
+     * @param userId target user ID.
+     * @return component name of the app and class to deliver SMS messages to
+     */
+    public static ComponentName getDefaultSmsApplicationAsUser(Context context,
+            boolean updateIfNeeded, int userId) {
         final long token = Binder.clearCallingIdentity();
         try {
             ComponentName component = null;
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 06378ba..23ea237 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -21,6 +21,7 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.os.Binder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Rlog;
@@ -307,4 +308,17 @@
         Rlog.e(LOG_TAG, "Phone process is down, cannot check carrier privileges");
         return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
     }
+
+    /**
+     * Throws if the caller is not of a shell (or root) UID.
+     *
+     * @param callingUid pass Binder.callingUid().
+     */
+    public static void enforceShellOnly(int callingUid, String message) {
+        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
+            return; // okay
+        }
+
+        throw new SecurityException(message + ": Only shell user can call it");
+    }
 }
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 0b8a02a..4d765d3 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -37,7 +37,8 @@
         "junit.framework",
     ],
 
-    droiddoc_options: ["stubsourceonly"],
+    droiddoc_options: ["-stubsourceonly"],
+    metalava_enabled: false,
     compile_dex: true,
 }
 
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 5eba017..37158e5 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -26,5 +26,6 @@
     ],
 
     srcs_lib_whitelist_pkgs: ["android"],
+    metalava_enabled: false,
     compile_dex: true,
 }
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index ea615b9..0a0d50c 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -40,7 +40,8 @@
         "junit.textui",
     ],
 
-    droiddoc_options: ["stubsourceonly"],
+    droiddoc_options: ["-stubsourceonly"],
+    metalava_enabled: false,
     compile_dex: true
 }
 
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 4a6fe49..976848c 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -106,9 +106,8 @@
     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
     private static final String APP_LAUNCH_CMD = "am start -W -n";
     private static final String SUCCESS_MESSAGE = "Status: ok";
-    private static final String WARNING_MESSAGE = "Warning:";
+    private static final String TOTAL_TIME_MESSAGE = "TotalTime:";
     private static final String COMPILE_SUCCESS = "Success";
-    private static final String THIS_TIME = "ThisTime:";
     private static final String LAUNCH_ITERATION = "LAUNCH_ITERATION - %d";
     private static final String TRACE_ITERATION = "TRACE_ITERATION-%d";
     private static final String LAUNCH_ITERATION_PREFIX = "LAUNCH_ITERATION";
@@ -247,8 +246,14 @@
                     mIterationCycle = false;
                     // In the "applaunch.txt" file, trail launches is referenced using
                     // "TRIAL_LAUNCH"
-                    String appPkgName = mNameToIntent.get(launch.getApp())
-                        .getComponent().getPackageName();
+                    Intent startIntent = mNameToIntent.get(launch.getApp());
+                    if (startIntent == null) {
+                        Log.w(TAG, "App does not exist: " + launch.getApp());
+                        mResult.putString(mNameToResultKey.get(launch.getApp()),
+                            "App does not exist");
+                        continue;
+                    }
+                    String appPkgName = startIntent.getComponent().getPackageName();
                     if (SPEED_PROFILE_FILTER.equals(launch.getCompilerFilter())) {
                         assertTrue(String.format("Not able to compile the app : %s", appPkgName),
                               compileApp(VERIFY_FILTER, appPkgName));
@@ -808,15 +813,13 @@
             String launchTime = "-1";
             String cpuCycles = "-1";
             String majorFaults = "-1";
-            boolean coldLaunchSuccess = false;
-            boolean hotLaunchSuccess = false;
+            boolean launchSuccess = false;
             try {
                 InputStream inputStream = new FileInputStream(parcelDesc.getFileDescriptor());
                 /* SAMPLE OUTPUT : Cold launch
                 Starting: Intent { cmp=com.google.android.calculator/com.android.calculator2.Calculator }
                 Status: ok
                 Activity: com.google.android.calculator/com.android.calculator2.Calculator
-                ThisTime: 357
                 TotalTime: 357
                 WaitTime: 377
                 Complete*/
@@ -825,7 +828,6 @@
                 Warning: Activity not started, its current task has been brought to the front
                 Status: ok
                 Activity: com.google.android.calculator/com.android.calculator2.CalculatorGoogle
-                ThisTime: 60
                 TotalTime: 60
                 WaitTime: 67
                 Complete*/
@@ -836,54 +838,37 @@
                 Total test time,1.462129,seconds,*/
                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
                         inputStream));
-                String line = null;
-                int lineCount = 1;
+                String line;
                 mBufferedWriter.newLine();
                 mBufferedWriter.write(headerInfo);
                 mBufferedWriter.newLine();
                 while ((line = bufferedReader.readLine()) != null) {
-                    if (lineCount == 2 && line.startsWith(SUCCESS_MESSAGE)) {
-                        coldLaunchSuccess = true;
+                    mBufferedWriter.write(line);
+                    mBufferedWriter.newLine();
+                    if (line.startsWith(SUCCESS_MESSAGE)) {
+                        launchSuccess = true;
                     }
-                    if (lineCount == 2 && line.startsWith(WARNING_MESSAGE)) {
-                        hotLaunchSuccess = true;
+                    if (!launchSuccess) {
+                        continue;
                     }
                     // Parse TotalTime which is the launch time
-                    if (coldLaunchSuccess && lineCount == 5) {
-                        String launchSplit[] = line.split(":");
-                        launchTime = launchSplit[1].trim();
-                    }
-                    if (hotLaunchSuccess && lineCount == 6) {
+                    if (line.startsWith(TOTAL_TIME_MESSAGE)) {
                         String launchSplit[] = line.split(":");
                         launchTime = launchSplit[1].trim();
                     }
 
                     if (mSimplePerfAppOnly) {
-                        // Parse simpleperf output.
-                        if ((lineCount == 9 && coldLaunchSuccess)
-                                || (lineCount == 10 && hotLaunchSuccess)) {
-                            if (!line.contains("cpu-cycles")) {
-                                Log.e(TAG, "Error in simpleperf output");
-                            } else {
-                                cpuCycles = line.split(",")[0].trim();
-                            }
-                        } else if ((lineCount == 10 && coldLaunchSuccess)
-                                || (lineCount == 11 && hotLaunchSuccess)) {
-                            if (!line.contains("major-faults")) {
-                                Log.e(TAG, "Error in simpleperf output");
-                            } else {
-                                majorFaults = line.split(",")[0].trim();
-                            }
+                        if (line.contains(",cpu-cycles,")) {
+                            cpuCycles = line.split(",")[0].trim();
+                        } else if (line.contains(",major-faults,")) {
+                            majorFaults = line.split(",")[0].trim();
                         }
                     }
-                    mBufferedWriter.write(line);
-                    mBufferedWriter.newLine();
-                    lineCount++;
                 }
                 mBufferedWriter.flush();
                 inputStream.close();
             } catch (IOException e) {
-                Log.w(TAG, "Error writing the launch file", e);
+                Log.w(TAG, "Error parsing launch time and writing to file", e);
             }
             return new AppLaunchResult(launchTime, cpuCycles, majorFaults);
         }
diff --git a/tests/DexLoggerIntegrationTests/AndroidManifest.xml b/tests/DexLoggerIntegrationTests/AndroidManifest.xml
index a847e8f..a9f01ed 100644
--- a/tests/DexLoggerIntegrationTests/AndroidManifest.xml
+++ b/tests/DexLoggerIntegrationTests/AndroidManifest.xml
@@ -17,10 +17,10 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.frameworks.dexloggertest">
 
-    <!-- Tests feature introduced in P (27) -->
+    <!-- Tests feature introduced in P (28) -->
     <uses-sdk
-        android:minSdkVersion="27"
-        android:targetSdkVersion="27" />
+        android:minSdkVersion="28"
+        android:targetSdkVersion="28" />
 
     <uses-permission android:name="android.permission.READ_LOGS" />
 
diff --git a/tests/ImfTest/Android.mk b/tests/ImfTest/Android.mk
deleted file mode 100644
index a8f5b08..0000000
--- a/tests/ImfTest/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := ImfTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/ImfTest/AndroidManifest.xml b/tests/ImfTest/AndroidManifest.xml
deleted file mode 100644
index 82dbe75..0000000
--- a/tests/ImfTest/AndroidManifest.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
-        package="com.android.imftest">
-
-   <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-   <application>
-    
-        <activity android:name=".samples.InputTypeActivity" android:label="Input Type Activity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-                
-        <activity android:name=".samples.ButtonActivity" android:label="Button Activity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.BigEditTextActivityNonScrollablePanScan" android:label="Big ET !Scroll Pan/Scan">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".samples.ManyEditTextActivityNoScrollPanScan" android:label="ManyEditTextActivityNoScrollPanScan">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.BigEditTextActivityNonScrollableResize" android:label="Big ET !Scroll Resize">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.BigEditTextActivityScrollablePanScan" android:label="Big ET Scroll Pan/Scan">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.BigEditTextActivityScrollableResize" android:label="Big ET Scroll Resize">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".samples.EditTextActivityDialog" android:label="ET Dialog">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".samples.ManyEditTextActivityScrollPanScan" android:label="ManyEditTextActivityScrollPanScan">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.ManyEditTextActivityScrollResize" android:label="ManyEditTextActivityScrollResize">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".samples.BottomEditTextActivityPanScan" android:label="BottomEditTextActivityPanScan">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.BottomEditTextActivityResize" android:label="BottomEditTextActivityResize">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name=".samples.OneEditTextActivitySelected" android:label="OneEditTextActivitySelected">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-    
-        <activity android:name=".samples.OneEditTextActivityNotSelected" android:label="OneEditTextActivityNotSelected">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-         
-        <activity android:name=".samples.AutoCompleteTextViewActivityPortrait" android:label="AutoCompleteTextViewActivityPortrait" android:screenOrientation="portrait">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>
-   
-        <activity android:name=".samples.AutoCompleteTextViewActivityLandscape" android:label="AutoCompleteTextViewActivityLandscape" android:screenOrientation="landscape">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>   
-        
-        <activity android:name=".samples.DialogActivity" android:label="DialogActivity" android:screenOrientation="portrait">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.IMF_TEST" />
-            </intent-filter>
-        </activity>              
-          
-    </application>
-    
-</manifest>
diff --git a/tests/ImfTest/res/layout/dialog_edit_text_no_scroll.xml b/tests/ImfTest/res/layout/dialog_edit_text_no_scroll.xml
deleted file mode 100644
index 1a2b7eb..0000000
--- a/tests/ImfTest/res/layout/dialog_edit_text_no_scroll.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:padding="20dip"
-    android:orientation="vertical">
-            
-    <View
-    	android:id="@+id/blank"
-    	android:layout_height="0dip"
-    	android:layout_width="match_parent"
-    	android:layout_weight="1"/>
-    	
-    <EditText
-        android:id="@+id/dialog_edit_text"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:scrollHorizontally="true"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-</LinearLayout>
diff --git a/tests/ImfTest/res/layout/full_screen_edit_text.xml b/tests/ImfTest/res/layout/full_screen_edit_text.xml
deleted file mode 100644
index e760ac1..0000000
--- a/tests/ImfTest/res/layout/full_screen_edit_text.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/samples/SampleCode/res/layout/baseline_1.xml
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<EditText xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/data" 
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:minLines="15"
-    android:gravity="top"/>
-
diff --git a/tests/ImfTest/res/layout/one_edit_text_activity.xml b/tests/ImfTest/res/layout/one_edit_text_activity.xml
deleted file mode 100644
index 0558228..0000000
--- a/tests/ImfTest/res/layout/one_edit_text_activity.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/samples/SampleCode/res/layout/baseline_1.xml
-**
-** Copyright 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.
-*/
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
->
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:baselineAligned="false">
-
-        <View android:id="@+id/blank"
-            android:layout_height="0dip"
-            android:layout_width="match_parent"
-            android:layout_weight="1"
-        />
-
-        <EditText android:id="@+id/dialog_edit_text"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:scrollHorizontally="true"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-        />
-    </LinearLayout>
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:background="@android:drawable/divider_horizontal_dark"
-    />
-</LinearLayout>
diff --git a/tests/ImfTest/res/layout/sample_edit_text.xml b/tests/ImfTest/res/layout/sample_edit_text.xml
deleted file mode 100644
index 3ff6767..0000000
--- a/tests/ImfTest/res/layout/sample_edit_text.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/samples/SampleCode/res/layout/baseline_1.xml
-**
-** Copyright 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.
-*/
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
->
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="?android:attr/listPreferredItemHeight"
-        android:orientation="horizontal"
-        android:baselineAligned="false"
-        android:gravity="center_vertical"
-    >
-
-        <TextView android:id="@+id/label"
-            android:layout_width="100dip"
-            android:layout_height="wrap_content"
-            android:gravity="right|center_vertical"
-        />
-
-        <EditText android:id="@+id/data"
-            android:layout_width="0dip"
-            android:layout_weight="1"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="8dip"
-        />
-    </LinearLayout>
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:background="@android:drawable/divider_horizontal_dark"
-    />
-</LinearLayout>
diff --git a/tests/ImfTest/res/values/config.xml b/tests/ImfTest/res/values/config.xml
deleted file mode 100644
index 5ae40a3..0000000
--- a/tests/ImfTest/res/values/config.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
- * Copyright (c) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
--->
-<resources>
-    <bool name="def_expect_ime_autopop">false</bool>
-</resources>
diff --git a/tests/ImfTest/res/values/strings.xml b/tests/ImfTest/res/values/strings.xml
deleted file mode 100644
index fc87480..0000000
--- a/tests/ImfTest/res/values/strings.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Strings for sample activities -->
-    <string name="normal_edit_text_label">Normal</string>
-    <string name="uri_edit_text_label">Uri</string>
-    <string name="email_address_edit_text_label">Email Address</string>
-    <string name="email_subject_edit_text_label">Email Subject</string>
-    <string name="email_content_edit_text_label">Email Content</string>
-    <string name="person_name_edit_text_label">Person Name</string>
-    <string name="postal_address_edit_text_label">Postal Address</string>
-    <string name="password_edit_text_label">Password</string>
-    <string name="search_string_edit_text_label">Search String</string>
-    <string name="web_edit_text_label">Web Edit Text</string>
-    <string name="signed_number_edit_text_label">Signed Number</string>
-    <string name="decimal_number_edit_text_label">Decimal Number</string>
-    <string name="phone_number_edit_text_label">Phone Number</string>
-    <string name="normal_datetime_edit_text_label">Datetime</string>
-    <string name="date_edit_text_label">Date</string>
-    <string name="time_edit_text_label">Time</string>
-    <string name="cap_chars_edit_text_label">Cap Chars</string>
-    <string name="cap_words_edit_text_label">Cap Words</string>
-    <string name="multiline_edit_text_label">Multiline</string>
-    <string name="search_edit_text_label">Search (flag)</string>
-    <string name="cap_sentences_edit_text_label">Cap Sentences</string>
-    <string name="auto_complete_edit_text_label">Auto Complete</string>
-    <string name="auto_correct_edit_text_label">Auto Correct</string>
-    <string name="test_dialog">Test Dialog</string>
-    <string name="open_dialog_scrollable">open scrollable dialog</string>
-    <string name="open_dialog_nonscrollable">open nonscrollable dialog</string>
-    
-    
-</resources>
diff --git a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
deleted file mode 100644
index 6115fd5..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.provider.MediaStore;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.AutoCompleteTextView;
-import android.widget.ArrayAdapter;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-
-import com.android.internal.R;
-
-/*
- * Activity with AutoCompleteTextView forced to landscape mode
- */
-public class AutoCompleteTextViewActivityLandscape extends Activity 
-{
-   @Override
-   public void onCreate(Bundle savedInstanceState) 
-   {
-       super.onCreate(savedInstanceState);
-    
-       setContentView(R.layout.auto_complete_list);
-
-       ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
-               android.R.layout.simple_dropdown_item_1line, COUNTRIES);
-       AutoCompleteTextView textView = findViewById(R.id.edit);
-       textView.setAdapter(adapter);
-   }
-
-   static final String[] COUNTRIES = new String[] {
-   "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
-   "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
-   "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
-   "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
-   "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
-   "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
-   "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
-   "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
-   "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
-   "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
-   "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czechia",
-   "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
-   "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
-   "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
-   "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
-   "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
-   "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
-   "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
-   "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
-   "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
-   "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
-   "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
-   "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
-   "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
-   "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
-   "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
-   "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
-   "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
-   "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
-   "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
-   "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
-   "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
-   "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
-   "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
-   "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
-   "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
-   "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
-   "Ukraine", "United Arab Emirates", "United Kingdom",
-   "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
-   "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
-   "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
-   };
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java
deleted file mode 100644
index 253c50f..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.AutoCompleteTextView;
-import android.widget.ArrayAdapter;
-
-import com.android.internal.R;
-
-/*
- * Activity with AutoCompleteTextView (Candidate bar should not appear)
- */
-public class AutoCompleteTextViewActivityPortrait extends Activity 
-{
-   @Override
-   public void onCreate(Bundle savedInstanceState) 
-   {
-       super.onCreate(savedInstanceState);
-       
-       setContentView(R.layout.auto_complete_list);
-
-       ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
-               android.R.layout.simple_dropdown_item_1line, COUNTRIES);
-       AutoCompleteTextView textView = findViewById(R.id.edit);
-       textView.setAdapter(adapter);
-   }
-
-   static final String[] COUNTRIES = new String[] {
-   "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
-   "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
-   "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
-   "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
-   "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
-   "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
-   "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
-   "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
-   "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
-   "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
-   "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czechia",
-   "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
-   "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
-   "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
-   "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
-   "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
-   "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
-   "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
-   "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
-   "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
-   "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
-   "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
-   "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
-   "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
-   "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
-   "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
-   "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
-   "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
-   "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
-   "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
-   "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
-   "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
-   "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
-   "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
-   "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
-   "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
-   "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
-   "Ukraine", "United Arab Emirates", "United Kingdom",
-   "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
-   "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
-   "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
-   };
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScan.java b/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScan.java
deleted file mode 100644
index 033082f..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScan.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-
-public class BigEditTextActivityNonScrollablePanScan extends Activity {
-    
-    private View mRootView;
-    private View mDefaultFocusedView;
-    
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        
-        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-        
-        mRootView = new LinearLayout(this);
-        ((LinearLayout) mRootView).setOrientation(LinearLayout.VERTICAL);
-        mRootView.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        View view = getLayoutInflater().inflate(
-                R.layout.full_screen_edit_text, ((LinearLayout) mRootView), false);
-        
-        ((LinearLayout) mRootView).addView(view);
-        
-        mDefaultFocusedView = view.findViewById(R.id.data);
-        
-        setContentView(mRootView);
-    }
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResize.java b/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResize.java
deleted file mode 100644
index 8a16dea..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResize.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-
-public class BigEditTextActivityNonScrollableResize extends Activity {
-    
-    private View mRootView;
-    private View mDefaultFocusedView;
-    
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        
-        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
-        
-        mRootView = new LinearLayout(this);
-        ((LinearLayout) mRootView).setOrientation(LinearLayout.VERTICAL);
-        mRootView.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        View view = getLayoutInflater().inflate(
-                R.layout.full_screen_edit_text, ((LinearLayout) mRootView), false);
-        
-        ((LinearLayout) mRootView).addView(view);
-        
-        mDefaultFocusedView = view.findViewById(R.id.data);
-        
-        setContentView(mRootView);
-    }
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScan.java b/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScan.java
deleted file mode 100644
index b4fdc4c..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScan.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-
-public class BigEditTextActivityScrollablePanScan extends Activity {
-    
-    private View mRootView;
-    private View mDefaultFocusedView;
-    private LinearLayout mLayout;
-    
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        
-        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-        
-        mRootView = new ScrollView(this);
-        ((ScrollView) mRootView).setFillViewport(true);
-        mRootView.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        mLayout = new LinearLayout(this);
-        mLayout.setOrientation(LinearLayout.VERTICAL);
-        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        View view = getLayoutInflater().inflate(
-                R.layout.full_screen_edit_text, ((ScrollView) mRootView), false);
-        
-        mLayout.addView(view);
-        
-        ((ScrollView) mRootView).addView(mLayout);
-        mDefaultFocusedView = view.findViewById(R.id.data);
-        
-        setContentView(mRootView);
-    }
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityScrollableResize.java b/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityScrollableResize.java
deleted file mode 100644
index 757b6b5..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/BigEditTextActivityScrollableResize.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-
-public class BigEditTextActivityScrollableResize extends Activity {
-    
-    private View mRootView;
-    private View mDefaultFocusedView;
-    private LinearLayout mLayout;
-    
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        
-        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
-        
-        mRootView = new ScrollView(this);
-        ((ScrollView) mRootView).setFillViewport(true);
-        mRootView.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        mLayout = new LinearLayout(this);
-        mLayout.setOrientation(LinearLayout.VERTICAL);
-        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        View view = getLayoutInflater().inflate(
-                R.layout.full_screen_edit_text, ((ScrollView) mRootView), false);
-        
-        mLayout.addView(view);
-        
-        ((ScrollView) mRootView).addView(mLayout);
-        mDefaultFocusedView = view.findViewById(R.id.data);
-        
-        setContentView(mRootView);
-    }
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/BottomEditTextActivityPanScan.java b/tests/ImfTest/src/com/android/imftest/samples/BottomEditTextActivityPanScan.java
deleted file mode 100644
index 91a329d..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/BottomEditTextActivityPanScan.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.EditText;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import com.android.imftest.R;
-
-/*
- * Activity with EditText at the bottom (Pan&Scan)
- */
-public class BottomEditTextActivityPanScan extends Activity 
-{
-    private View mRootView;
-    private View mDefaultFocusedView;
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-        
-        mRootView = new LinearLayout(this);
-        ((LinearLayout) mRootView).setOrientation(LinearLayout.VERTICAL);
-        
-        View view = getLayoutInflater().inflate(R.layout.one_edit_text_activity, ((LinearLayout) mRootView), false);
-        mDefaultFocusedView = view.findViewById(R.id.dialog_edit_text);
-        ((LinearLayout) mRootView).addView(view);
-       
-        setContentView(mRootView);
-        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-    }  
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/BottomEditTextActivityResize.java b/tests/ImfTest/src/com/android/imftest/samples/BottomEditTextActivityResize.java
deleted file mode 100644
index c4c41bc..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/BottomEditTextActivityResize.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.EditText;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import com.android.imftest.R;
-
-/*
- * Activity with EditText at the bottom (Resize)
- */
-public class BottomEditTextActivityResize extends Activity 
-{
-    private View mRootView;
-    private View mDefaultFocusedView;
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-        
-        mRootView = new LinearLayout(this);
-        ((LinearLayout) mRootView).setOrientation(LinearLayout.VERTICAL);
-        
-        View view = getLayoutInflater().inflate(R.layout.one_edit_text_activity, ((LinearLayout) mRootView), false);
-        mDefaultFocusedView = view.findViewById(R.id.dialog_edit_text);
-        ((LinearLayout) mRootView).addView(view);
-       
-        setContentView(mRootView);
-        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
-    }  
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java b/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java
deleted file mode 100644
index dbaedf9..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Button;
-import android.widget.TextView;
-
-public class ButtonActivity extends Activity 
-{
-    static boolean mKeyboardIsActive = false;
-    public static final int BUTTON_ID = 0;
-    private View mRootView;
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-        final ButtonActivity instance = this;
-             
-        final Button myButton = new Button(this);
-        myButton.setClickable(true);
-        myButton.setText("Keyboard UP!");
-        myButton.setId(BUTTON_ID);
-        myButton.setFocusableInTouchMode(true);
-        myButton.setOnClickListener(new View.OnClickListener()
-        {
-            public void onClick (View v)
-            {
-                InputMethodManager imm = InputMethodManager.getInstance();
-                if (mKeyboardIsActive)
-                {
-                    imm.hideSoftInputFromInputMethod(v.getWindowToken(), 0);
-                    myButton.setText("Keyboard UP!");
-            
-                }
-                else
-                {
-                    myButton.requestFocusFromTouch();
-                    imm.showSoftInput(v, 0);
-                    myButton.setText("Keyboard DOWN!");
-                }
-               
-                mKeyboardIsActive = !mKeyboardIsActive;
-            }
-        });
-            
-       LinearLayout layout = new LinearLayout(this);
-       layout.setOrientation(LinearLayout.VERTICAL);
-       layout.addView(myButton);
-       setContentView(layout);
-       mRootView = layout;
-    }
-    
-    public View getRootView() {
-        return mRootView;
-    }
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/DialogActivity.java b/tests/ImfTest/src/com/android/imftest/samples/DialogActivity.java
deleted file mode 100644
index 3ed0386..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/DialogActivity.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.EditText;
-import android.widget.Button;
-import android.view.LayoutInflater;
-import android.app.Dialog;
-
-public class DialogActivity extends Activity {
-
-    private static final int DIALOG_WITHOUT_EDITTEXT = 0;
-    private static final int DIALOG_WITH_EDITTEXT = 1;
-
-    private LinearLayout mLayout;
-    private LayoutInflater mInflater;
-    private Button mButton1;
-    private Button mButton2;
-    private EditText mEditText;
-
-
-    @Override
-    protected void onCreate(Bundle icicle) 
-    {
-        super.onCreate(icicle);
-
-        mLayout = new LinearLayout(this);
-        mLayout.setOrientation(LinearLayout.VERTICAL);
-        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-
-        mButton1 = new Button(this);
-        mButton1.setText("Dialog WITHOUT EditText");//(R.string.open_dialog_scrollable);
-        mButton1.setOnClickListener(new View.OnClickListener() 
-        {
-            public void onClick(View v) 
-            {
-                showDialog(DIALOG_WITHOUT_EDITTEXT);
-            }
-        });
-
-        mButton2 = new Button(this);
-        mButton2.setText("Dialog WITH EditText");//(R.string.open_dialog_nonscrollable);
-        mButton2.setOnClickListener(new View.OnClickListener() 
-        {
-            public void onClick(View v) 
-            {
-                showDialog(DIALOG_WITH_EDITTEXT);
-            }
-        });
-
-        mEditText = new EditText(this);
-        mLayout.addView(mEditText);
-        mLayout.addView(mButton1);
-        mLayout.addView(mButton2);
-
-        setContentView(mLayout);
-    }
-
-    @Override
-    protected Dialog onCreateDialog(int id) 
-    {
-        switch (id) 
-        {
-            case DIALOG_WITHOUT_EDITTEXT:
-                return createDialog(false);
-            case DIALOG_WITH_EDITTEXT:
-                return createDialog(true);
-        }
-
-        return super.onCreateDialog(id);
-    }
-
-    protected Dialog createDialog(boolean bEditText) 
-    {
-        LinearLayout layout;        
-        layout = new LinearLayout(this);
-        layout.setOrientation(LinearLayout.VERTICAL);
-        
-        if(bEditText)
-        {
-            EditText editText;
-            editText = new EditText(this);
-            layout.addView(editText);
-        }
-        
-        Dialog d = new Dialog(this);
-        d.setTitle("The DIALOG!!!");
-        d.setCancelable(true);
-        d.setContentView(layout);
-        return d;
-    }
-
- }
diff --git a/tests/ImfTest/src/com/android/imftest/samples/EditTextActivityDialog.java b/tests/ImfTest/src/com/android/imftest/samples/EditTextActivityDialog.java
deleted file mode 100644
index 2591b7c..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/EditTextActivityDialog.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-
-public class EditTextActivityDialog extends Activity {
-    
-    private static final int SCROLLABLE_DIALOG_ID = 0;
-    private static final int NONSCROLLABLE_DIALOG_ID = 1;
-    
-    private LinearLayout mLayout;
-    private ScrollView mScrollView;
-    private LayoutInflater mInflater;
-    private Button mButton1;
-    private Button mButton2;
-    
-    
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        
-        mLayout = new LinearLayout(this);
-        mLayout.setOrientation(LinearLayout.VERTICAL);
-        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-        
-        mButton1 = new Button(this);
-        mButton1.setText(R.string.open_dialog_scrollable);
-        mButton1.setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                showDialog(SCROLLABLE_DIALOG_ID);
-            }
-        });
-        
-        mButton2 = new Button(this);
-        mButton2.setText(R.string.open_dialog_nonscrollable);
-        mButton2.setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                showDialog(NONSCROLLABLE_DIALOG_ID);
-            }
-        });
-        
-        mLayout.addView(mButton1);
-        mLayout.addView(mButton2);
-        
-        setContentView(mLayout);
-    }
-    
-    @Override
-    protected Dialog onCreateDialog(int id) {
-        switch (id) {
-            case SCROLLABLE_DIALOG_ID:
-                return createDialog(true);
-            case NONSCROLLABLE_DIALOG_ID:
-                return createDialog(false);
-        }
-
-        return super.onCreateDialog(id);
-    }
-    
-    protected Dialog createDialog(boolean scrollable) {
-        View layout;
-        EditText editText;
-        
-        if (scrollable) {
-            layout = new ScrollView(EditTextActivityDialog.this);
-            ((ScrollView) layout).setMinimumHeight(mLayout.getHeight());
-            
-            ((ScrollView) layout).addView((
-                    LinearLayout) View.inflate(EditTextActivityDialog.this, 
-                    R.layout.dialog_edit_text_no_scroll, null));
-        } else {
-            layout = View.inflate(EditTextActivityDialog.this, 
-                    R.layout.dialog_edit_text_no_scroll, null);
-        }
-        
-        Dialog d = new Dialog(EditTextActivityDialog.this);
-        d.setTitle(getString(R.string.test_dialog));
-        d.setCancelable(true);
-        d.setContentView(layout);
-        return d;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
deleted file mode 100644
index 299e6bb..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.app.Activity;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-import android.widget.TextView;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-
-public class InputTypeActivity extends Activity {
-
-    private LinearLayout mLayout;
-    private ScrollView mScrollView;
-    private LayoutInflater mInflater;
-    private ViewGroup mParent;
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mScrollView = new ScrollView(this);
-        
-        mLayout = new LinearLayout(this);
-        mLayout.setOrientation(LinearLayout.VERTICAL);
-        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-
-        mInflater = getLayoutInflater();
-        mParent = mLayout;
-        
-        /* Normal Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL, 
-                R.string.normal_edit_text_label));
-        
-        /* Normal Edit Text w/Cap Chars Flag*/
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS, 
-                R.string.cap_chars_edit_text_label));
-        
-        /* Normal Edit Text w/Cap Words Flag*/
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS, 
-                R.string.cap_words_edit_text_label));
-        
-        /* Normal Edit Text w/Cap Multiline Flag */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE, 
-                R.string.multiline_edit_text_label));
-        
-        /* Normal Edit Text w/Cap Sentences Flag */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES, 
-                R.string.cap_sentences_edit_text_label));
-        
-        /* Normal Edit Text w/Auto-complete Flag */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE, 
-                R.string.auto_complete_edit_text_label));
-        
-        /* Normal Edit Text w/Auto-correct Flag */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_NORMAL|EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT, 
-                R.string.auto_correct_edit_text_label));
-        
-        /* Uri Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_URI, 
-                R.string.uri_edit_text_label));
-        
-        /* Email Address Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS, 
-                R.string.email_address_edit_text_label));
-        
-        /* Email Subject Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT, 
-                R.string.email_subject_edit_text_label));
-        
-        /* Email Content Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_LONG_MESSAGE, 
-                R.string.email_content_edit_text_label));
-        
-        /* Person Name Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME, 
-                R.string.person_name_edit_text_label));
-        
-        /* Postal Address Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_POSTAL_ADDRESS, 
-                R.string.postal_address_edit_text_label));
-        
-        /* Password Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_PASSWORD, 
-                R.string.password_edit_text_label));
-        
-        /* Web Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT, 
-                R.string.web_edit_text_label));
-        
-        /* Signed Number Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_NUMBER|EditorInfo.TYPE_NUMBER_FLAG_SIGNED, 
-                R.string.signed_number_edit_text_label));
-        
-        /* Decimal Number Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_NUMBER|EditorInfo.TYPE_NUMBER_FLAG_DECIMAL, 
-                R.string.decimal_number_edit_text_label));
-        
-        /* Phone Number Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_PHONE, 
-                R.string.phone_number_edit_text_label));
-        
-        /* Normal Datetime Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_DATETIME|EditorInfo.TYPE_DATETIME_VARIATION_NORMAL, 
-                R.string.normal_datetime_edit_text_label));
-        
-        /* Date Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_DATETIME|EditorInfo.TYPE_DATETIME_VARIATION_DATE, 
-                R.string.date_edit_text_label));
-        
-        /* Time Edit Text */
-        mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_DATETIME|EditorInfo.TYPE_DATETIME_VARIATION_TIME, 
-                R.string.time_edit_text_label));
-            
-        mScrollView.addView(mLayout);
-        setContentView(mScrollView);
-    }
-    
-    private View buildEntryView(int inputType, int label) {
-
-        
-        View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
-        
-        EditText editText = (EditText) view.findViewById(R.id.data);
-        editText.setInputType(inputType);
-        
-        TextView textView = (TextView) view.findViewById(R.id.label);
-        textView.setText(label);
-        
-        return view;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityNoScrollPanScan.java b/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityNoScrollPanScan.java
deleted file mode 100644
index 646e480..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityNoScrollPanScan.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.ScrollView;
-
-import com.android.internal.R;
-
-/*
- * Full screen of EditTexts (Non-Scrollable, Pan&Scan)
- */
-public class ManyEditTextActivityNoScrollPanScan extends Activity 
-{
-    public static final int NUM_EDIT_TEXTS = 9;
-
-    private View mRootView;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-
-        mRootView = new LinearLayout(this);
-        ((LinearLayout) mRootView).setOrientation(LinearLayout.VERTICAL);
-
-        for (int i=0; i<NUM_EDIT_TEXTS; i++) 
-        {
-            final EditText editText = new EditText(this);
-            editText.setText(String.valueOf(i));
-            editText.setId(i);
-            ((LinearLayout) mRootView).addView(editText);
-        }
-        setContentView(mRootView);
-        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-    }  
-
-    public View getRootView() {
-        return mRootView;
-    }
-
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityScrollPanScan.java b/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityScrollPanScan.java
deleted file mode 100644
index 0387e1e..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityScrollPanScan.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.ScrollView;
-
-import com.android.internal.R;
-
-/*
- * Full screen of EditTexts (Scrollable, Pan&Scan)
- */
-public class ManyEditTextActivityScrollPanScan extends Activity 
-{
-    public static final int NUM_EDIT_TEXTS = 12;
-
-    private View mRootView;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-        mRootView = new ScrollView(this);
-
-        LinearLayout layout = new LinearLayout(this);
-        layout.setOrientation(LinearLayout.VERTICAL);
-
-        for (int i=0; i<NUM_EDIT_TEXTS; i++) 
-        {
-            final EditText editText = new EditText(this);
-            editText.setText(String.valueOf(i));
-            editText.setId(i);
-            layout.addView(editText);
-        }
-
-        ((ScrollView) mRootView).addView(layout);
-        setContentView(mRootView);
-        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-    }   
-
-    public View getRootView() {
-        return mRootView;
-    }
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityScrollResize.java b/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityScrollResize.java
deleted file mode 100644
index 7793b55..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/ManyEditTextActivityScrollResize.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.widget.EditText;
-import android.widget.ScrollView;
-
-/*
- * Full screen of EditTexts (Scrollable, Resize)
- */
-public class ManyEditTextActivityScrollResize extends Activity 
-{
-    public static final int NUM_EDIT_TEXTS = 12;
-    
-    private View mRootView;
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-        mRootView = new ScrollView(this);
-       
-        LinearLayout layout = new LinearLayout(this);
-        layout.setOrientation(LinearLayout.VERTICAL);
-       
-        for (int i=0; i<NUM_EDIT_TEXTS; i++) 
-        {
-            final EditText editText = new EditText(this);
-            editText.setText(String.valueOf(i));
-            editText.setId(i);
-            layout.addView(editText);
-        }
-
-        ((ScrollView) mRootView).addView(layout);
-        setContentView(mRootView);
-        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
-    }  
-
-    public View getRootView() {
-        return mRootView;
-    } 
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/OneEditTextActivityNotSelected.java b/tests/ImfTest/src/com/android/imftest/samples/OneEditTextActivityNotSelected.java
deleted file mode 100644
index c4be21c..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/OneEditTextActivityNotSelected.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.Debug;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.ScrollView;
-
-import com.android.internal.R;
-
-/*
- * Activity with non-EditText view selected initially
- */
-public class OneEditTextActivityNotSelected extends Activity 
-{
-    private View mRootView;
-    private View mDefaultFocusedView;
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-
-        LinearLayout layout = new LinearLayout(this);
-        layout.setOrientation(LinearLayout.VERTICAL);
-        mRootView = new ScrollView(this);
-
-        EditText editText = new EditText(this);
-        Button button = new Button(this);
-        button.setText("The focus is here.");
-        button.setFocusableInTouchMode(true);
-        button.requestFocus();
-        mDefaultFocusedView = button;
-        layout.addView(button);
-        layout.addView(editText);
-
-        ((ScrollView) mRootView).addView(layout);
-        setContentView(mRootView);
-    }  
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/OneEditTextActivitySelected.java b/tests/ImfTest/src/com/android/imftest/samples/OneEditTextActivitySelected.java
deleted file mode 100644
index 64882aa..0000000
--- a/tests/ImfTest/src/com/android/imftest/samples/OneEditTextActivitySelected.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.ScrollView;
-
-import com.android.internal.R;
-
-/*
- * Activity with EditText selected initially
- */
-public class OneEditTextActivitySelected extends Activity 
-{
-    private View mRootView;
-    private View mDefaultFocusedView;
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) 
-    {
-        super.onCreate(savedInstanceState);
-
-        LinearLayout layout = new LinearLayout(this);
-        layout.setOrientation(LinearLayout.VERTICAL);
-        mRootView = new ScrollView(this);
-        
-        EditText editText = new EditText(this);
-        editText.requestFocus();
-        mDefaultFocusedView = editText;
-        layout.addView(editText);
-
-        ((ScrollView) mRootView).addView(layout);
-        setContentView(mRootView);
-        
-        // set to resize so IME is always shown (and also so
-        // ImfBaseTestCase#destructiveCheckImeInitialState thinks it should always be shown
-        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
-    }
-
-    public View getRootView() {
-        return mRootView;
-    }
-    
-    public View getDefaultFocusedView() {
-        return mDefaultFocusedView;
-    }
-}
diff --git a/tests/ImfTest/tests/Android.mk b/tests/ImfTest/tests/Android.mk
deleted file mode 100644
index 14186d7..0000000
--- a/tests/ImfTest/tests/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_STATIC_JAVA_LIBRARIES := junit
-
-LOCAL_PACKAGE_NAME := ImfTestTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_INSTRUMENTATION_FOR := ImfTest
-
-include $(BUILD_PACKAGE)
diff --git a/tests/ImfTest/tests/AndroidManifest.xml b/tests/ImfTest/tests/AndroidManifest.xml
deleted file mode 100644
index c02fa0b..0000000
--- a/tests/ImfTest/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +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.
--->
-
-<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.imftest.tests">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!--
-    This declares that this app uses the instrumentation test runner targeting
-    the package of com.android.imftest.  To run the tests use the command:
-    "adb shell am instrument -w com.android.imftest.tests/android.test.InstrumentationTestRunner"
-    -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="com.android.imftest"
-                     android:label="imf tests"/>
-
-</manifest>
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
deleted file mode 100644
index 2db11c5..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-import com.android.imftest.R;
-
-
-public class BigEditTextActivityNonScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityNonScrollablePanScan> {
-
-    public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
-    
-    public BigEditTextActivityNonScrollablePanScanTests() {
-        super(BigEditTextActivityNonScrollablePanScan.class);
-    }
-    
-    @LargeTest
-    public void testAppAdjustmentPanScan() {
-        // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
-        View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
-            
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-        
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
deleted file mode 100644
index 1050794..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-import com.android.imftest.R;
-
-
-public class BigEditTextActivityNonScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityNonScrollableResize> {
-
-    public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
-    
-    public BigEditTextActivityNonScrollableResizeTests() {
-        super(BigEditTextActivityNonScrollableResize.class);
-    }
-    
-    @LargeTest
-    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        View rootView = ((BigEditTextActivityNonScrollableResize) mTargetActivity).getRootView();
-        View servedView = ((BigEditTextActivityNonScrollableResize) mTargetActivity).getDefaultFocusedView();
-         
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-            
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
deleted file mode 100644
index 1e848b0..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-import com.android.imftest.R;
-
-
-public class BigEditTextActivityScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityScrollablePanScan> {
-
-    public final String TAG = "BigEditTextActivityScrollablePanScanTests";
-    
-    public BigEditTextActivityScrollablePanScanTests() {
-        super(BigEditTextActivityScrollablePanScan.class);
-    }
-    
-    @LargeTest
-    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        View rootView = ((BigEditTextActivityScrollablePanScan) mTargetActivity).getRootView();
-        View servedView = ((BigEditTextActivityScrollablePanScan) mTargetActivity).getDefaultFocusedView();
-         
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-            
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
deleted file mode 100644
index de607d6..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-import com.android.imftest.R;
-
-
-public class BigEditTextActivityScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityScrollableResize> {
-
-    public final String TAG = "BigEditTextActivityScrollableResizeTests";
-    
-    public BigEditTextActivityScrollableResizeTests() {
-        super(BigEditTextActivityScrollableResize.class);
-    }
-    
-    @LargeTest
-    public void testAppAdjustmentPanScan() {       
-        // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        View rootView = ((BigEditTextActivityScrollableResize) mTargetActivity).getRootView();
-        View servedView = ((BigEditTextActivityScrollableResize) mTargetActivity).getDefaultFocusedView();
-          
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-            
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
deleted file mode 100644
index c521905..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-import com.android.imftest.R;
-
-
-public class BottomEditTextActivityPanScanTests extends ImfBaseTestCase<BottomEditTextActivityPanScan> {
-
-    public final String TAG = "BottomEditTextActivityPanScanTests";
-    
-    public BottomEditTextActivityPanScanTests() {
-        super(BottomEditTextActivityPanScan.class);
-    }
-    
-    @LargeTest
-    public void testAppAdjustmentPanScan() {
-        // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        View rootView = ((BottomEditTextActivityPanScan) mTargetActivity).getRootView();
-        View servedView = ((BottomEditTextActivityPanScan) mTargetActivity).getDefaultFocusedView();
-        
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-        
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityResizeTests.java
deleted file mode 100644
index 9a69fd5..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityResizeTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-import com.android.imftest.R;
-
-
-public class BottomEditTextActivityResizeTests extends ImfBaseTestCase<BottomEditTextActivityResize> {
-
-    public final String TAG = "BottomEditTextActivityResizeTests";
-    
-    public BottomEditTextActivityResizeTests() {
-        super(BottomEditTextActivityResize.class);
-    }
-    
-    @LargeTest
-    public void testAppAdjustmentResize() {
-        // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        View rootView = ((BottomEditTextActivityResize) mTargetActivity).getRootView();
-        View servedView = ((BottomEditTextActivityResize) mTargetActivity).getDefaultFocusedView();
-        
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-        
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
deleted file mode 100644
index f6f97b5..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-import android.widget.Button;
-
-
-public class ButtonActivityTest extends ImfBaseTestCase<ButtonActivity> {
-
-    final public String TAG = "ButtonActivityTest";
-    
-    public ButtonActivityTest() {
-        super(ButtonActivity.class);
-    }
-
-    @LargeTest
-    public void testButtonActivatesIme() {
-       
-        final Button button = (Button) mTargetActivity.findViewById(ButtonActivity.BUTTON_ID);
-        
-        // Push button
-        // Bring the target EditText into focus.
-        mTargetActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                button.requestFocus();
-            }
-        });
-        
-        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        
-        // Give it a couple seconds
-        pause(2000);
-        
-        // We should have initialized imm.mServedView and imm.mCurrentTextBoxAttribute
-        assertTrue(mImm.isActive());
-        // imm.mServedInputConnection should be null since Button doesn't override onCreateInputConnection().
-        assertFalse(mImm.isAcceptingText());
-        
-        destructiveCheckImeInitialState(mTargetActivity.getRootView(), button);
-        
-    }
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java
deleted file mode 100644
index 32f80a3..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.SystemClock;
-import android.test.InstrumentationTestCase;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-
-import com.android.imftest.R;
-
-public abstract class ImfBaseTestCase<T extends Activity> extends InstrumentationTestCase {
-
-    /*
-     * The amount of time we are willing to wait for the IME to appear after a user action
-     * before we give up and fail the test.
-     */
-    public final long WAIT_FOR_IME = 5000;
-
-    /*
-     * Unfortunately there is now way for us to know how tall the IME is,
-     * so we have to hard code a minimum and maximum value.
-     */
-    public final int IME_MIN_HEIGHT = 150;
-    public final int IME_MAX_HEIGHT = 300;
-
-    protected InputMethodManager mImm;
-    protected T mTargetActivity;
-    protected boolean mExpectAutoPop;
-    private Class<T> mTargetActivityClass;
-
-    public ImfBaseTestCase(Class<T> activityClass) {
-        mTargetActivityClass = activityClass;
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        final String packageName = getInstrumentation().getTargetContext().getPackageName();
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-        mTargetActivity = launchActivityWithIntent(packageName, mTargetActivityClass, intent);
-        // expect ime to auto pop up if device has no hard keyboard
-        int keyboardType = mTargetActivity.getResources().getConfiguration().keyboard;
-        mExpectAutoPop = (keyboardType  == Configuration.KEYBOARD_NOKEYS ||
-                keyboardType == Configuration.KEYBOARD_UNDEFINED);
-
-        mImm = InputMethodManager.getInstance();
-
-        KeyguardManager keyguardManager =
-            (KeyguardManager) getInstrumentation().getContext().getSystemService(
-                    Context.KEYGUARD_SERVICE);
-        keyguardManager.newKeyguardLock("imftest").disableKeyguard();
-    }
-    
-    // Utility test methods
-    public void verifyEditTextAdjustment(final View editText, int rootViewHeight) {
-
-        int[] origLocation = new int[2];
-        int[] newLocation = new int[2];
-
-        // Tell the keyboard to go away.
-        mImm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
-
-        // Bring the target EditText into focus.
-        mTargetActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                editText.requestFocus();
-            }
-        });
-
-        // Get the original location of the EditText.
-        editText.getLocationOnScreen(origLocation);
-
-        // Tap the EditText to bring up the IME.
-        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-
-        // Wait until the EditText pops above the IME or until we hit the timeout.
-        editText.getLocationOnScreen(newLocation);
-        long timeoutTime = SystemClock.uptimeMillis() + WAIT_FOR_IME;
-        while (newLocation[1] > rootViewHeight - IME_MIN_HEIGHT && SystemClock.uptimeMillis() < timeoutTime) {
-            editText.getLocationOnScreen(newLocation);
-            pause(100);
-        }
-
-        assertTrue(newLocation[1] <= rootViewHeight - IME_MIN_HEIGHT);
-
-        // Tell the keyboard to go away.
-        mImm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
-    }
-
-    public void destructiveCheckImeInitialState(View rootView, View servedView) {
-        int windowSoftInputMode = mTargetActivity.getWindow().getAttributes().softInputMode;
-        int adjustMode = windowSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
-        if (mExpectAutoPop && adjustMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
-            assertTrue(destructiveCheckImeUp(rootView, servedView));
-        } else {
-            assertFalse(destructiveCheckImeUp(rootView, servedView));
-        }
-    }
-
-    public boolean destructiveCheckImeUp(View rootView, View servedView) {
-        int origHeight;
-        int newHeight;
-
-        origHeight = rootView.getHeight();
-
-        // Tell the keyboard to go away.
-        mImm.hideSoftInputFromWindow(servedView.getWindowToken(), 0);
-
-        // Give it five seconds to adjust
-        newHeight = rootView.getHeight();
-        long timeoutTime = SystemClock.uptimeMillis() + WAIT_FOR_IME;
-        while (Math.abs(newHeight - origHeight) < IME_MIN_HEIGHT && SystemClock.uptimeMillis() < timeoutTime) {
-            newHeight = rootView.getHeight();
-        }
-
-        return (Math.abs(origHeight - newHeight) >= IME_MIN_HEIGHT);
-    }
-
-    void pause(int millis) {
-        try {
-            Thread.sleep(millis);
-        } catch (InterruptedException e) {
-        }
-    }
-
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityBaseTestCase.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityBaseTestCase.java
deleted file mode 100644
index 278efb1..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityBaseTestCase.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.app.Activity;
-import android.widget.EditText;
-
-
-public abstract class ManyEditTextActivityBaseTestCase<T extends Activity> extends ImfBaseTestCase<T> {
-  
-    public ManyEditTextActivityBaseTestCase(Class<T> activityClass){
-        super(activityClass);
-    }
-
-    public abstract void testAllEditTextsAdjust();
-
-    public void verifyAllEditTextAdjustment(int numEditTexts, int rootViewHeight) {
-
-        for (int i = 0; i < numEditTexts; i++) {
-            final EditText lastEditText = (EditText) mTargetActivity.findViewById(i);
-            verifyEditTextAdjustment(lastEditText, rootViewHeight);
-        }
-
-    }
-
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityNoScrollPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityNoScrollPanScanTests.java
deleted file mode 100644
index 4f8d14e..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityNoScrollPanScanTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-
-
-public class ManyEditTextActivityNoScrollPanScanTests extends ManyEditTextActivityBaseTestCase<ManyEditTextActivityNoScrollPanScan> {
-
-    public final String TAG = "ManyEditTextActivityNoScrollPanScanTests";
-    
-    public ManyEditTextActivityNoScrollPanScanTests() {
-        super(ManyEditTextActivityNoScrollPanScan.class);
-    }
-
-   
-    @LargeTest
-    public void testAllEditTextsAdjust() {
-        verifyAllEditTextAdjustment(mTargetActivity.NUM_EDIT_TEXTS, 
-                mTargetActivity.getRootView().getMeasuredHeight());
-    }
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityScrollPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityScrollPanScanTests.java
deleted file mode 100644
index 7f98f7f..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityScrollPanScanTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-
-
-public class ManyEditTextActivityScrollPanScanTests extends ManyEditTextActivityBaseTestCase<ManyEditTextActivityScrollPanScan> {
-
-    public final String TAG = "ManyEditTextActivityScrollPanScanTests";
-    
-    
-    public ManyEditTextActivityScrollPanScanTests() {
-        super(ManyEditTextActivityScrollPanScan.class);
-    }
-    
-    @LargeTest
-    public void testAllEditTextsAdjust() {
-        verifyAllEditTextAdjustment(mTargetActivity.NUM_EDIT_TEXTS, 
-                mTargetActivity.getRootView().getMeasuredHeight());
-    }
-
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityScrollResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityScrollResizeTests.java
deleted file mode 100644
index 68dae87..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ManyEditTextActivityScrollResizeTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-
-
-public class ManyEditTextActivityScrollResizeTests extends ManyEditTextActivityBaseTestCase<ManyEditTextActivityScrollResize> {
-
-    public final String TAG = "ManyEditTextActivityScrollResizeTests";
-    
-    
-    public ManyEditTextActivityScrollResizeTests() {
-        super(ManyEditTextActivityScrollResize.class);
-    }
-
-    @LargeTest
-    public void testAllEditTextsAdjust() {
-        verifyAllEditTextAdjustment(mTargetActivity.NUM_EDIT_TEXTS, 
-                mTargetActivity.getRootView().getMeasuredHeight());
-    }
-
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
deleted file mode 100644
index 6147d3c..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.View;
-
-
-public class OneEditTextActivityNotSelectedTests extends ImfBaseTestCase<OneEditTextActivityNotSelected> {
-
-    public final String TAG = "OneEditTextActivityNotSelectedTests";
-    
-    public OneEditTextActivityNotSelectedTests() {
-        super(OneEditTextActivityNotSelected.class);
-    }
-    
-    @LargeTest
-    public void testSoftKeyboardNoAutoPop() {
-        
-        // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        assertFalse(mImm.isAcceptingText());
-        
-        View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
-        View servedView = ((OneEditTextActivityNotSelected) mTargetActivity).getDefaultFocusedView();
-        
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-        
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivitySelectedTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivitySelectedTests.java
deleted file mode 100644
index 42fcd66..0000000
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivitySelectedTests.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.imftest.samples;
-
-import com.android.imftest.R;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-import android.view.View;
-
-
-public class OneEditTextActivitySelectedTests extends ImfBaseTestCase<OneEditTextActivitySelected> {
-
-    public final String TAG = "OneEditTextActivitySelectedTests";
-    
-    public OneEditTextActivitySelectedTests() {
-        super(OneEditTextActivitySelected.class);
-    }
-    
-    @LargeTest
-    public void testSoftKeyboardAutoPop() {
-        
-        // Give the IME 2 seconds to appear.
-        pause(2000);
-        
-        assertTrue(mImm.isAcceptingText());
-        
-        View rootView = ((OneEditTextActivitySelected) mTargetActivity).getRootView();
-        View servedView = ((OneEditTextActivitySelected) mTargetActivity).getDefaultFocusedView();
-        
-        assertNotNull(rootView);
-        assertNotNull(servedView);
-        
-        destructiveCheckImeInitialState(rootView, servedView);
-        
-        verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-    }
-    
-}
diff --git a/tests/NativeProcessesMemoryTest/Android.bp b/tests/NativeProcessesMemoryTest/Android.bp
new file mode 100644
index 0000000..f2625bf
--- /dev/null
+++ b/tests/NativeProcessesMemoryTest/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_test_host {
+    name: "native-processes-memory-test",
+    srcs: ["src/**/*.java"],
+
+    libs: ["tradefed"],
+    test_suites: ["general-tests"],
+}
diff --git a/tests/NativeProcessesMemoryTest/AndroidTest.xml b/tests/NativeProcessesMemoryTest/AndroidTest.xml
new file mode 100644
index 0000000..0f326fd
--- /dev/null
+++ b/tests/NativeProcessesMemoryTest/AndroidTest.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.
+-->
+<configuration description="Runs the native processes memory tests">
+    <option name="test-suite-tag" value="native-processes-memory-test" />
+    <test class="com.android.tradefed.testtype.HostTest" >
+        <option name="class" value="com.android.tests.nativeprocesses.NativeProcessesMemoryTest" />
+    </test>
+</configuration>
diff --git a/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java b/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java
new file mode 100644
index 0000000..51302ce
--- /dev/null
+++ b/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.nativeprocesses;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ByteArrayInputStreamSource;
+import com.android.tradefed.result.LogDataType;
+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 org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.InputMismatchException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Scanner;
+
+/**
+ * Test to gather native processes count and memory usage.
+ *
+ * Native processes are parsed from dumpsys meminfo --oom -c
+ *
+ * <pre>
+ * time,35857009,35857009
+ * oom,native,331721,N/A
+ * proc,native,init,1,2715,N/A,e
+ * proc,native,init,445,1492,N/A,e
+ * ...
+ * </pre>
+ *
+ * For each native process we also look at its showmap output, and gather the PSS, VSS, and RSS.
+ * The showmap output is also saved to test logs.
+ *
+ * The metrics reported are:
+ *
+ * <pre>
+ *   - number of native processes
+ *   - total memory use of native processes
+ *   - memory usage of each native process (one measurement for each process)
+ * </pre>
+ */
+@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");
+
+    // -c gives us a compact output which is comma separated
+    private static final String DUMPSYS_MEMINFO_OOM_CMD = "dumpsys meminfo --oom -c";
+
+    private static final String SEPARATOR = ",";
+    private static final String LINE_SEPARATOR = "\\n";
+
+    // key used to report the number of native processes
+    private static final String NUM_NATIVE_PROCESSES_KEY = "Num_native_processes";
+
+    // identity for summing over MemoryMetric
+    private final MemoryMetric mZero = new MemoryMetric(0, 0, 0);
+
+    private ITestDevice mTestDevice;
+
+    @Test
+    public void run() throws DeviceNotAvailableException {
+        // showmap requires root, we enable it here for the rest of the test
+        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
+        metrics.addTestMetric(
+                NUM_NATIVE_PROCESSES_KEY, Integer.toString(nativeProcesses.size()));
+    }
+
+    /** Samples memory of all processes and logs the memory use. */
+    private void sampleAndLogAllProcesses(Map<String, List<String>> nativeProcesses)
+            throws DeviceNotAvailableException {
+        for (Map.Entry<String, List<String>> entry : nativeProcesses.entrySet()) {
+            String processName = entry.getKey();
+            if (PROCESSES_TO_IGNORE.contains(processName)) {
+                continue;
+            }
+
+            // for all pids associated with this process name, record their memory usage
+            List<MemoryMetric> allMemsForProcess = new ArrayList<>();
+            for (String pid : entry.getValue()) {
+                Optional<MemoryMetric> mem = snapMemoryUsage(processName, pid);
+                if (mem.isPresent()) {
+                    allMemsForProcess.add(mem.get());
+                }
+            }
+
+            // if for some reason a process does not have any MemoryMetric, don't log it
+            if (allMemsForProcess.isEmpty()) {
+                continue;
+            }
+
+            // combine all the memory metrics of process with the same name
+            MemoryMetric combined = allMemsForProcess.stream().reduce(mZero, MemoryMetric::sum);
+            logMemoryMetric(processName, combined);
+        }
+    }
+
+    @Override
+    public void setDevice(ITestDevice device) {
+        mTestDevice = device;
+    }
+
+    @Override
+    public ITestDevice getDevice() {
+        return mTestDevice;
+    }
+
+    /**
+     * Query system for a list of native process.
+     *
+     * @return a map from process name to a list of pids that share the same name
+     */
+    private Map<String, List<String>> collectNativeProcesses() throws DeviceNotAvailableException {
+        HashMap<String, List<String>> nativeProcesses = new HashMap<>();
+        String memInfo = getDevice().executeShellCommand(DUMPSYS_MEMINFO_OOM_CMD);
+
+        for (String line : memInfo.split(LINE_SEPARATOR)) {
+            String[] splits = line.split(SEPARATOR);
+            // ignore lines that don't list a native process
+            if (splits.length < 4 || !splits[0].equals("proc") || !splits[1].equals("native")) {
+                continue;
+            }
+
+            String processName = splits[2];
+            String pid = splits[3];
+            if (nativeProcesses.containsKey(processName)) {
+                nativeProcesses.get(processName).add(pid);
+            } else {
+                nativeProcesses.put(processName, new ArrayList<>(Arrays.asList(pid)));
+            }
+        }
+        return nativeProcesses;
+    }
+
+    /** Logs an entire showmap output to the test logs. */
+    private void logShowmap(String label, String showmap) {
+        try (ByteArrayInputStreamSource source =
+                new ByteArrayInputStreamSource(showmap.getBytes())) {
+            logs.addTestLog(label + "_showmap", LogDataType.TEXT, source);
+        }
+    }
+
+    /**
+     * Extract VSS, PSS, and RSS from showmap of a process.
+     * The showmap output is also added to test logs.
+     */
+    private Optional<MemoryMetric> snapMemoryUsage(String processName, String pid)
+            throws DeviceNotAvailableException {
+        // TODO(zhin): copied from com.android.tests.sysmem.host.Metrics#sample(), extract?
+        String showmap = getDevice().executeShellCommand("showmap " + pid);
+        logShowmap(processName + "_" + pid, showmap);
+
+        // CHECKSTYLE:OFF Generated code
+        // The last lines of the showmap output looks like:
+        // ------- -------- -------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
+        // virtual                     shared   shared  private  private
+        //    size      RSS      PSS    clean    dirty    clean    dirty     swap  swapPSS   # object
+        // -------- -------- -------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
+        //   12848     4240     1543     2852       64       36     1288        0        0  171 TOTAL
+        // CHECKSTYLE:ON Generated code
+        try {
+            int pos = showmap.lastIndexOf("----");
+            Scanner sc = new Scanner(showmap.substring(pos));
+            sc.next();
+            long vss = sc.nextLong();
+            long rss = sc.nextLong();
+            long pss = sc.nextLong();
+            return Optional.of(new MemoryMetric(pss, rss, vss));
+        } catch (InputMismatchException e) {
+            // this might occur if we have transient processes, it was collected earlier,
+            // but by the time we look at showmap the process is gone
+            CLog.e("Unable to parse MemoryMetric from showmap of pid: " + pid + " processName: "
+                    + processName);
+            CLog.e(showmap);
+            return Optional.empty();
+        }
+    }
+
+    /** Logs a MemoryMetric of a process. */
+    private void logMemoryMetric(String processName, MemoryMetric memoryMetric) {
+        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. */
+    private final class MemoryMetric {
+        final long pss;
+        final long rss;
+        final long vss;
+
+        MemoryMetric(long pss, long rss, long vss) {
+            this.pss = pss;
+            this.rss = rss;
+            this.vss = vss;
+        }
+
+        MemoryMetric sum(MemoryMetric other) {
+            return new MemoryMetric(
+                    pss + other.pss, rss + other.rss, vss + other.vss);
+        }
+    }
+}
diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk
index fe65ecc..c225e17 100644
--- a/tests/NetworkSecurityConfigTest/Android.mk
+++ b/tests/NetworkSecurityConfigTest/Android.mk
@@ -7,7 +7,6 @@
 
 LOCAL_JAVA_LIBRARIES := \
     android.test.runner \
-    bouncycastle \
     conscrypt \
     android.test.base \
 
diff --git a/tests/RemoteDisplayProvider/Android.mk b/tests/RemoteDisplayProvider/Android.mk
index e827ec2..43bf024 100644
--- a/tests/RemoteDisplayProvider/Android.mk
+++ b/tests/RemoteDisplayProvider/Android.mk
@@ -18,9 +18,9 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := RemoteDisplayProviderTest
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := system_current
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR = $(LOCAL_PATH)/res
-LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay.stubs
+LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index e529b93..750e2fb 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -38,6 +38,7 @@
     libbacktrace \
     libbase \
     libbinder \
+    libbinderthreadstate \
     libc++ \
     libcrypto \
     libcutils \
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
index ba1a2ea..6dae3f1 100644
--- a/tests/net/AndroidManifest.xml
+++ b/tests/net/AndroidManifest.xml
@@ -44,6 +44,7 @@
     <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
     <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
     <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
+    <uses-permission android:name="android.permission.NETWORK_STACK" />
 
     <application>
         <uses-library android:name="android.test.runner" />
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/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
new file mode 100644
index 0000000..122edba
--- /dev/null
+++ b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.netlink;
+
+import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+import static android.os.Process.INVALID_UID;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_RCVTIMEO;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.netlink.StructNlMsgHdr;
+import android.os.Process;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+import android.support.test.InstrumentationRegistry;
+import android.system.Os;
+import android.system.StructTimeval;
+import android.util.Log;
+import java.io.FileDescriptor;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import libcore.util.HexEncoding;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class InetDiagSocketTest {
+    private final String TAG = "InetDiagSocketTest";
+    private ConnectivityManager mCm;
+    private Context mContext;
+    private final static int SOCKET_TIMEOUT_MS = 100;
+
+    @Before
+    public void setUp() throws Exception {
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        mContext = instrumentation.getTargetContext();
+        mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    private class Connection {
+        public int socketDomain;
+        public int socketType;
+        public InetAddress localAddress;
+        public InetAddress remoteAddress;
+        public InetAddress localhostAddress;
+        public InetSocketAddress local;
+        public InetSocketAddress remote;
+        public int protocol;
+        public FileDescriptor localFd;
+        public FileDescriptor remoteFd;
+
+        public FileDescriptor createSocket() throws Exception {
+            return Os.socket(socketDomain, socketType, protocol);
+        }
+
+        public Connection(String to, String from) throws Exception {
+            remoteAddress = InetAddress.getByName(to);
+            if (from != null) {
+                localAddress = InetAddress.getByName(from);
+            } else {
+                localAddress = (remoteAddress instanceof Inet4Address) ?
+                        Inet4Address.getByName("localhost") : Inet6Address.getByName("::");
+            }
+            if ((localAddress instanceof Inet4Address) && (remoteAddress instanceof Inet4Address)) {
+                socketDomain = AF_INET;
+                localhostAddress = Inet4Address.getByName("localhost");
+            } else {
+                socketDomain = AF_INET6;
+                localhostAddress = Inet6Address.getByName("::");
+            }
+        }
+
+        public void close() throws Exception {
+            Os.close(localFd);
+        }
+    }
+
+    private class TcpConnection extends Connection {
+        public TcpConnection(String to, String from) throws Exception {
+            super(to, from);
+            protocol = IPPROTO_TCP;
+            socketType = SOCK_STREAM;
+
+            remoteFd = createSocket();
+            Os.bind(remoteFd, remoteAddress, 0);
+            Os.listen(remoteFd, 10);
+            int remotePort = ((InetSocketAddress) Os.getsockname(remoteFd)).getPort();
+
+            localFd = createSocket();
+            Os.bind(localFd, localAddress, 0);
+            Os.connect(localFd, remoteAddress, remotePort);
+
+            local = (InetSocketAddress) Os.getsockname(localFd);
+            remote = (InetSocketAddress) Os.getpeername(localFd);
+        }
+
+        public void close() throws Exception {
+            super.close();
+            Os.close(remoteFd);
+        }
+    }
+    private class UdpConnection extends Connection {
+        public UdpConnection(String to, String from) throws Exception {
+            super(to, from);
+            protocol = IPPROTO_UDP;
+            socketType = SOCK_DGRAM;
+
+            remoteFd = null;
+            localFd = createSocket();
+            Os.bind(localFd, localAddress, 0);
+
+            Os.connect(localFd, remoteAddress, 7);
+            local = (InetSocketAddress) Os.getsockname(localFd);
+            remote = new InetSocketAddress(remoteAddress, 7);
+        }
+    }
+
+    private void checkConnectionOwnerUid(int protocol, InetSocketAddress local,
+                                         InetSocketAddress remote, boolean expectSuccess) {
+        final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID;
+        final int uid = mCm.getConnectionOwnerUid(protocol, local, remote);
+        assertEquals(expectedUid, uid);
+    }
+
+    private int findLikelyFreeUdpPort(UdpConnection conn) throws Exception {
+        UdpConnection udp = new UdpConnection(conn.remoteAddress.getHostAddress(),
+                conn.localAddress.getHostAddress());
+        final int localPort = udp.local.getPort();
+        udp.close();
+        return localPort;
+    }
+
+    public void checkGetConnectionOwnerUid(String to, String from) throws Exception {
+        /**
+         * For TCP connections, create a test connection and verify that this
+         * {protocol, local, remote} socket result in receiving a valid UID.
+         */
+        TcpConnection tcp = new TcpConnection(to, from);
+        checkConnectionOwnerUid(tcp.protocol, tcp.local, tcp.remote, true);
+        checkConnectionOwnerUid(IPPROTO_UDP, tcp.local, tcp.remote, false);
+        checkConnectionOwnerUid(tcp.protocol, new InetSocketAddress(0), tcp.remote, false);
+        checkConnectionOwnerUid(tcp.protocol, tcp.local, new InetSocketAddress(0), false);
+        tcp.close();
+
+        /**
+         * For UDP connections, either a complete match {protocol, local, remote} or a
+         * partial match {protocol, local} should return a valid UID.
+         */
+        UdpConnection udp = new UdpConnection(to,from);
+        checkConnectionOwnerUid(udp.protocol, udp.local, udp.remote, true);
+        checkConnectionOwnerUid(udp.protocol, udp.local, new InetSocketAddress(0), true);
+        checkConnectionOwnerUid(IPPROTO_TCP, udp.local, udp.remote, false);
+        checkConnectionOwnerUid(udp.protocol, new InetSocketAddress(findLikelyFreeUdpPort(udp)),
+                udp.remote, false);
+        udp.close();
+    }
+
+    @Test
+    public void testGetConnectionOwnerUid() throws Exception {
+        checkGetConnectionOwnerUid("::", null);
+        checkGetConnectionOwnerUid("::", "::");
+        checkGetConnectionOwnerUid("0.0.0.0", null);
+        checkGetConnectionOwnerUid("0.0.0.0", "0.0.0.0");
+        checkGetConnectionOwnerUid("127.0.0.1", null);
+        checkGetConnectionOwnerUid("127.0.0.1", "127.0.0.2");
+        checkGetConnectionOwnerUid("::1", null);
+        checkGetConnectionOwnerUid("::1", "::1");
+    }
+
+    // Hexadecimal representation of InetDiagReqV2 request.
+    private static final String INET_DIAG_REQ_V2_UDP_INET4_HEX =
+            // struct nlmsghdr
+            "48000000" +     // length = 72
+            "1400" +         // type = SOCK_DIAG_BY_FAMILY
+            "0103" +         // flags = NLM_F_REQUEST | NLM_F_DUMP
+            "00000000" +     // seqno
+            "00000000" +     // pid (0 == kernel)
+            // struct inet_diag_req_v2
+            "02" +           // family = AF_INET
+            "11" +           // protcol = IPPROTO_UDP
+            "00" +           // idiag_ext
+            "00" +           // pad
+            "ffffffff" +     // idiag_states
+            // inet_diag_sockid
+            "a5de" +         // idiag_sport = 42462
+            "b971" +         // idiag_dport = 47473
+            "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2
+            "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8
+            "00000000" +     // idiag_if
+            "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE
+    private static final byte[] INET_DIAG_REQ_V2_UDP_INET4_BYTES =
+            HexEncoding.decode(INET_DIAG_REQ_V2_UDP_INET4_HEX.toCharArray(), false);
+
+    @Test
+    public void testInetDiagReqV2UdpInet4() throws Exception {
+        InetSocketAddress local = new InetSocketAddress(InetAddress.getByName("10.0.100.2"),
+                42462);
+        InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"),
+                47473);
+        final byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_UDP, local, remote, AF_INET,
+                (short) (NLM_F_REQUEST | NLM_F_DUMP));
+        assertArrayEquals(INET_DIAG_REQ_V2_UDP_INET4_BYTES, msg);
+    }
+
+    // Hexadecimal representation of InetDiagReqV2 request.
+    private static final String INET_DIAG_REQ_V2_TCP_INET6_HEX =
+            // struct nlmsghdr
+            "48000000" +     // length = 72
+            "1400" +         // type = SOCK_DIAG_BY_FAMILY
+            "0100" +         // flags = NLM_F_REQUEST
+            "00000000" +     // seqno
+            "00000000" +     // pid (0 == kernel)
+            // struct inet_diag_req_v2
+            "0a" +           // family = AF_INET6
+            "06" +           // protcol = IPPROTO_TCP
+            "00" +           // idiag_ext
+            "00" +           // pad
+            "ffffffff" +     // idiag_states
+                // inet_diag_sockid
+                "a5de" +         // idiag_sport = 42462
+                "b971" +         // idiag_dport = 47473
+                "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b
+                "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8
+                "00000000" +     // idiag_if
+                "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE
+    private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_BYTES =
+            HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_HEX.toCharArray(), false);
+
+    @Test
+    public void testInetDiagReqV2TcpInet6() throws Exception {
+        InetSocketAddress local = new InetSocketAddress(
+                InetAddress.getByName("fe80::86c9:b2ff:fe6a:ed4b"), 42462);
+        InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"),
+                47473);
+        byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET6,
+                NLM_F_REQUEST);
+
+        assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_BYTES, msg);
+    }
+
+    // Hexadecimal representation of InetDiagReqV2 request.
+    private static final String INET_DIAG_MSG_HEX =
+            // struct nlmsghdr
+            "58000000" +     // length = 88
+            "1400" +         // type = SOCK_DIAG_BY_FAMILY
+            "0200" +         // flags = NLM_F_MULTI
+            "00000000" +     // seqno
+            "f5220000" +     // pid (0 == kernel)
+            // struct inet_diag_msg
+            "0a" +           // family = AF_INET6
+            "01" +           // idiag_state
+            "00" +           // idiag_timer
+            "00" +           // idiag_retrans
+                // inet_diag_sockid
+                "a817" +     // idiag_sport = 43031
+                "960f" +     // idiag_dport = 38415
+                "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b
+                "00000000000000000000ffff08080808" + // idiag_dst = 8.8.8.8
+                "00000000" + // idiag_if
+                "ffffffffffffffff" + // idiag_cookie = INET_DIAG_NOCOOKIE
+            "00000000" +     // idiag_expires
+            "00000000" +     // idiag_rqueue
+            "00000000" +     // idiag_wqueue
+            "a3270000" +     // idiag_uid
+            "A57E1900";      // idiag_inode
+    private static final byte[] INET_DIAG_MSG_BYTES =
+            HexEncoding.decode(INET_DIAG_MSG_HEX.toCharArray(), false);
+
+    @Test
+    public void testParseInetDiagResponse() throws Exception {
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(INET_DIAG_MSG_BYTES);
+        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+        final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
+        assertNotNull(msg);
+
+        assertTrue(msg instanceof InetDiagMessage);
+        final InetDiagMessage inetDiagMsg = (InetDiagMessage) msg;
+        assertEquals(10147, inetDiagMsg.mStructInetDiagMsg.idiag_uid);
+
+        final StructNlMsgHdr hdr = inetDiagMsg.getHeader();
+        assertNotNull(hdr);
+        assertEquals(NetlinkConstants.SOCK_DIAG_BY_FAMILY, hdr.nlmsg_type);
+        assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
+        assertEquals(0, hdr.nlmsg_seq);
+        assertEquals(8949, hdr.nlmsg_pid);
+    }
+}
diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java
index d46facf..8604860 100644
--- a/tests/net/java/android/net/util/SharedLogTest.java
+++ b/tests/net/java/android/net/util/SharedLogTest.java
@@ -44,6 +44,8 @@
         final SharedLog logLevel2a = logTop.forSubComponent("twoA");
         final SharedLog logLevel2b = logTop.forSubComponent("twoB");
         logLevel2b.e("2b or not 2b");
+        logLevel2b.e("No exception", null);
+        logLevel2b.e("Wait, here's one", new Exception("Test"));
         logLevel2a.w("second post?");
 
         final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
@@ -54,6 +56,9 @@
         final String[] expected = {
             " - MARK first post!",
             " - [twoB] ERROR 2b or not 2b",
+            " - [twoB] ERROR No exception",
+            // No stacktrace in shared log, only in logcat
+            " - [twoB] ERROR Wait, here's one: Test",
             " - [twoA] WARN second post?",
             " - still logging",
             " - [twoA.three] 3 >> 2",
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e3db7e8..1c77fcc 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -79,6 +79,7 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -248,7 +249,7 @@
         @Spy private Resources mResources;
         private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
 
-        MockContext(Context base) {
+        MockContext(Context base, ContentProvider settingsProvider) {
             super(base);
 
             mResources = spy(base.getResources());
@@ -260,7 +261,7 @@
                     });
 
             mContentResolver = new MockContentResolver();
-            mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+            mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
         }
 
         @Override
@@ -1048,7 +1049,9 @@
             Looper.prepare();
         }
 
-        mServiceContext = new MockContext(InstrumentationRegistry.getContext());
+        FakeSettingsProvider.clearSettingsProvider();
+        mServiceContext = new MockContext(InstrumentationRegistry.getContext(),
+                new FakeSettingsProvider());
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
         LocalServices.addService(
                 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
@@ -1067,13 +1070,13 @@
 
         // Ensure that the default setting for Captive Portals is used for most tests
         setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
-        setMobileDataAlwaysOn(false);
+        setAlwaysOnNetworks(false);
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
     }
 
     @After
     public void tearDown() throws Exception {
-        setMobileDataAlwaysOn(false);
+        setAlwaysOnNetworks(false);
         if (mCellNetworkAgent != null) {
             mCellNetworkAgent.disconnect();
             mCellNetworkAgent = null;
@@ -1086,6 +1089,7 @@
             mEthernetNetworkAgent.disconnect();
             mEthernetNetworkAgent = null;
         }
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     private static int transportToLegacyType(int transport) {
@@ -2023,7 +2027,7 @@
 
     @Test
     public void testNetworkGoesIntoBackgroundAfterLinger() {
-        setMobileDataAlwaysOn(true);
+        setAlwaysOnNetworks(true);
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities()
                 .build();
@@ -2768,10 +2772,10 @@
         Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
     }
 
-    private void setMobileDataAlwaysOn(boolean enable) {
+    private void setAlwaysOnNetworks(boolean enable) {
         ContentResolver cr = mServiceContext.getContentResolver();
         Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
-        mService.updateMobileDataAlwaysOn();
+        mService.updateAlwaysOnNetworks();
         waitForIdle();
     }
 
@@ -2793,7 +2797,7 @@
     public void testBackgroundNetworks() throws Exception {
         // Create a background request. We can't do this ourselves because ConnectivityService
         // doesn't have an API for it. So just turn on mobile data always on.
-        setMobileDataAlwaysOn(true);
+        setAlwaysOnNetworks(true);
         final NetworkRequest request = new NetworkRequest.Builder().build();
         final NetworkRequest fgRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_FOREGROUND).build();
@@ -2991,7 +2995,7 @@
 
         // Turn on mobile data always on. The factory starts looking again.
         testFactory.expectAddRequests(1);
-        setMobileDataAlwaysOn(true);
+        setAlwaysOnNetworks(true);
         testFactory.waitForNetworkRequests(2);
         assertTrue(testFactory.getMyStartRequested());
 
@@ -3011,7 +3015,7 @@
 
         // Turn off mobile data always on and expect the request to disappear...
         testFactory.expectRemoveRequests(1);
-        setMobileDataAlwaysOn(false);
+        setAlwaysOnNetworks(false);
         testFactory.waitForNetworkRequests(1);
 
         // ...  and cell data to be torn down.
@@ -4532,4 +4536,78 @@
         mCellNetworkAgent.disconnect();
         mCm.unregisterNetworkCallback(networkCallback);
     }
+
+    @Test
+    public void testDataActivityTracking() throws RemoteException {
+        final TestNetworkCallback networkCallback = new TestNetworkCallback();
+        final NetworkRequest networkRequest = new NetworkRequest.Builder()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .build();
+        mCm.registerNetworkCallback(networkRequest, networkCallback);
+
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        final LinkProperties cellLp = new LinkProperties();
+        cellLp.setInterfaceName(MOBILE_IFNAME);
+        mCellNetworkAgent.sendLinkProperties(cellLp);
+        reset(mNetworkManagementService);
+        mCellNetworkAgent.connect(true);
+        networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
+                eq(ConnectivityManager.TYPE_MOBILE));
+
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        final LinkProperties wifiLp = new LinkProperties();
+        wifiLp.setInterfaceName(WIFI_IFNAME);
+        mWiFiNetworkAgent.sendLinkProperties(wifiLp);
+
+        // Network switch
+        reset(mNetworkManagementService);
+        mWiFiNetworkAgent.connect(true);
+        networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
+                eq(ConnectivityManager.TYPE_WIFI));
+        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
+
+        // Disconnect wifi and switch back to cell
+        reset(mNetworkManagementService);
+        mWiFiNetworkAgent.disconnect();
+        networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        assertNoCallbacks(networkCallback);
+        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
+                eq(ConnectivityManager.TYPE_MOBILE));
+
+        // reconnect wifi
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        wifiLp.setInterfaceName(WIFI_IFNAME);
+        mWiFiNetworkAgent.sendLinkProperties(wifiLp);
+        mWiFiNetworkAgent.connect(true);
+        networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+
+        // Disconnect cell
+        reset(mNetworkManagementService);
+        mCellNetworkAgent.disconnect();
+        networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        // LOST callback is triggered earlier than removing idle timer. Broadcast should also be
+        // sent as network being switched. Ensure rule removal for cell will not be triggered
+        // unexpectedly before network being removed.
+        waitForIdle();
+        verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
+        verify(mNetworkManagementService, times(1)).removeNetwork(
+                eq(mCellNetworkAgent.getNetwork().netId));
+
+        // Disconnect wifi
+        ConditionVariable cv = waitForConnectivityBroadcasts(1);
+        reset(mNetworkManagementService);
+        mWiFiNetworkAgent.disconnect();
+        waitFor(cv);
+        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+
+        // Clean up
+        mCm.unregisterNetworkCallback(networkCallback);
+    }
 }
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/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 40d5544..a6ed9f2 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -33,6 +33,7 @@
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
+import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -75,6 +76,8 @@
 import android.net.NetworkState;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
+import android.net.dhcp.DhcpServer;
+import android.net.dhcp.DhcpServingParams;
 import android.net.ip.IpServer;
 import android.net.ip.RouterAdvertisementDaemon;
 import android.net.util.InterfaceParams;
@@ -85,6 +88,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.INetworkManagementService;
+import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
@@ -146,6 +150,7 @@
     @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
     @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
     @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
+    @Mock private DhcpServer mDhcpServer;
     @Mock private INetd mNetd;
 
     private final MockTetheringDependencies mTetheringDependencies =
@@ -240,6 +245,12 @@
                 public INetd getNetdService() {
                     return mNetd;
                 }
+
+                @Override
+                public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+                        DhcpServingParams params, SharedLog log) {
+                    return mDhcpServer;
+                }
             };
         }
 
@@ -333,6 +344,7 @@
         mServiceContext = new MockContext(mContext);
         mContentResolver = new MockContentResolver(mServiceContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
         mIntents = new Vector<>();
         mBroadcastReceiver = new BroadcastReceiver() {
             @Override
@@ -343,12 +355,16 @@
         mServiceContext.registerReceiver(mBroadcastReceiver,
                 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
         mTetheringDependencies.reset();
-        mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
-                                   mLooper.getLooper(), mSystemProperties,
-                                   mTetheringDependencies);
+        mTethering = makeTethering();
         verify(mNMService).registerTetheringStatsProvider(any(), anyString());
     }
 
+    private Tethering makeTethering() {
+        return new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
+                mLooper.getLooper(), mSystemProperties,
+                mTetheringDependencies);
+    }
+
     @After
     public void tearDown() {
         mServiceContext.unregisterReceiver(mBroadcastReceiver);
@@ -597,6 +613,18 @@
 
         sendIPv6TetherUpdates(upstreamState);
         verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
+        verify(mDhcpServer, times(1)).start();
+    }
+
+    @Test
+    public void workingMobileUsbTethering_IPv4LegacyDhcp() {
+        Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
+        mTethering = makeTethering();
+        final NetworkState upstreamState = buildMobileIPv4UpstreamState();
+        runUsbTethering(upstreamState);
+        sendIPv6TetherUpdates(upstreamState);
+
+        verify(mDhcpServer, never()).start();
     }
 
     @Test
@@ -620,6 +648,7 @@
         verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
         verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
         verify(mRouterAdvertisementDaemon, times(1)).start();
+        verify(mDhcpServer, times(1)).start();
 
         sendIPv6TetherUpdates(upstreamState);
         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
@@ -633,6 +662,7 @@
 
         verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
         verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
+        verify(mDhcpServer, times(1)).start();
         verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
         verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
                 TEST_XLAT_MOBILE_IFNAME);
@@ -649,6 +679,7 @@
         runUsbTethering(upstreamState);
 
         verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
+        verify(mDhcpServer, times(1)).start();
         verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
 
         // Then 464xlat comes up
@@ -671,6 +702,8 @@
         // Forwarding was not re-added for v6 (still times(1))
         verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
         verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
+        // DHCP not restarted on downstream (still times(1))
+        verify(mDhcpServer, times(1)).start();
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
index bb31230..5217784 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
@@ -225,13 +225,4 @@
         final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
         assertFalse(cfg.enableLegacyDhcpServer);
     }
-
-    @Test
-    public void testNewDhcpServerDefault() {
-        Settings.Global.putString(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, null);
-
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
-        // TODO: change to false when new server is promoted to default
-        assertTrue(cfg.enableLegacyDhcpServer);
-    }
 }
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/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/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
deleted file mode 100644
index f621660..0000000
--- a/tools/aapt2/ConfigDescription.cpp
+++ /dev/null
@@ -1,999 +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 "ConfigDescription.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 {
-
-static const char* kWildcardName = "any";
-
-const ConfigDescription& ConfigDescription::DefaultConfig() {
-  static ConfigDescription config = {};
-  return config;
-}
-
-static bool parseMcc(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->mcc = 0;
-    return true;
-  }
-  const char* c = name;
-  if (tolower(*c) != 'm') return false;
-  c++;
-  if (tolower(*c) != 'c') return false;
-  c++;
-  if (tolower(*c) != 'c') return false;
-  c++;
-
-  const char* val = c;
-
-  while (*c >= '0' && *c <= '9') {
-    c++;
-  }
-  if (*c != 0) return false;
-  if (c - val != 3) return false;
-
-  int d = atoi(val);
-  if (d != 0) {
-    if (out) out->mcc = d;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseMnc(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->mnc = 0;
-    return true;
-  }
-  const char* c = name;
-  if (tolower(*c) != 'm') return false;
-  c++;
-  if (tolower(*c) != 'n') return false;
-  c++;
-  if (tolower(*c) != 'c') return false;
-  c++;
-
-  const char* val = c;
-
-  while (*c >= '0' && *c <= '9') {
-    c++;
-  }
-  if (*c != 0) return false;
-  if (c - val == 0 || c - val > 3) return false;
-
-  if (out) {
-    out->mnc = atoi(val);
-    if (out->mnc == 0) {
-      out->mnc = ACONFIGURATION_MNC_ZERO;
-    }
-  }
-
-  return true;
-}
-
-static bool parseLayoutDirection(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
-          ResTable_config::LAYOUTDIR_ANY;
-    return true;
-  } else if (strcmp(name, "ldltr") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
-          ResTable_config::LAYOUTDIR_LTR;
-    return true;
-  } else if (strcmp(name, "ldrtl") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
-          ResTable_config::LAYOUTDIR_RTL;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
-          ResTable_config::SCREENSIZE_ANY;
-    return true;
-  } else if (strcmp(name, "small") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
-          ResTable_config::SCREENSIZE_SMALL;
-    return true;
-  } else if (strcmp(name, "normal") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
-          ResTable_config::SCREENSIZE_NORMAL;
-    return true;
-  } else if (strcmp(name, "large") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
-          ResTable_config::SCREENSIZE_LARGE;
-    return true;
-  } else if (strcmp(name, "xlarge") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
-          ResTable_config::SCREENSIZE_XLARGE;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
-          ResTable_config::SCREENLONG_ANY;
-    return true;
-  } else if (strcmp(name, "long") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
-          ResTable_config::SCREENLONG_YES;
-    return true;
-  } else if (strcmp(name, "notlong") == 0) {
-    if (out)
-      out->screenLayout =
-          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
-          ResTable_config::SCREENLONG_NO;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseScreenRound(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->screenLayout2 =
-          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
-          ResTable_config::SCREENROUND_ANY;
-    return true;
-  } else if (strcmp(name, "round") == 0) {
-    if (out)
-      out->screenLayout2 =
-          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
-          ResTable_config::SCREENROUND_YES;
-    return true;
-  } else if (strcmp(name, "notround") == 0) {
-    if (out)
-      out->screenLayout2 =
-          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
-          ResTable_config::SCREENROUND_NO;
-    return true;
-  }
-  return false;
-}
-
-static bool parseWideColorGamut(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->colorMode =
-          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
-          ResTable_config::WIDE_COLOR_GAMUT_ANY;
-    return true;
-  } else if (strcmp(name, "widecg") == 0) {
-    if (out)
-      out->colorMode =
-          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
-          ResTable_config::WIDE_COLOR_GAMUT_YES;
-    return true;
-  } else if (strcmp(name, "nowidecg") == 0) {
-    if (out)
-      out->colorMode =
-          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
-          ResTable_config::WIDE_COLOR_GAMUT_NO;
-    return true;
-  }
-  return false;
-}
-
-static bool parseHdr(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->colorMode =
-          (out->colorMode & ~ResTable_config::MASK_HDR) |
-          ResTable_config::HDR_ANY;
-    return true;
-  } else if (strcmp(name, "highdr") == 0) {
-    if (out)
-      out->colorMode =
-          (out->colorMode & ~ResTable_config::MASK_HDR) |
-          ResTable_config::HDR_YES;
-    return true;
-  } else if (strcmp(name, "lowdr") == 0) {
-    if (out)
-      out->colorMode =
-          (out->colorMode & ~ResTable_config::MASK_HDR) |
-          ResTable_config::HDR_NO;
-    return true;
-  }
-  return false;
-}
-
-static bool parseOrientation(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->orientation = out->ORIENTATION_ANY;
-    return true;
-  } else if (strcmp(name, "port") == 0) {
-    if (out) out->orientation = out->ORIENTATION_PORT;
-    return true;
-  } else if (strcmp(name, "land") == 0) {
-    if (out) out->orientation = out->ORIENTATION_LAND;
-    return true;
-  } else if (strcmp(name, "square") == 0) {
-    if (out) out->orientation = out->ORIENTATION_SQUARE;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseUiModeType(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_ANY;
-    return true;
-  } else if (strcmp(name, "desk") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_DESK;
-    return true;
-  } else if (strcmp(name, "car") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_CAR;
-    return true;
-  } else if (strcmp(name, "television") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_TELEVISION;
-    return true;
-  } else if (strcmp(name, "appliance") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_APPLIANCE;
-    return true;
-  } else if (strcmp(name, "watch") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_WATCH;
-    return true;
-  } else if (strcmp(name, "vrheadset") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
-                    ResTable_config::UI_MODE_TYPE_VR_HEADSET;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseUiModeNight(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
-                    ResTable_config::UI_MODE_NIGHT_ANY;
-    return true;
-  } else if (strcmp(name, "night") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
-                    ResTable_config::UI_MODE_NIGHT_YES;
-    return true;
-  } else if (strcmp(name, "notnight") == 0) {
-    if (out)
-      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
-                    ResTable_config::UI_MODE_NIGHT_NO;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseDensity(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->density = ResTable_config::DENSITY_DEFAULT;
-    return true;
-  }
-
-  if (strcmp(name, "anydpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_ANY;
-    return true;
-  }
-
-  if (strcmp(name, "nodpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_NONE;
-    return true;
-  }
-
-  if (strcmp(name, "ldpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_LOW;
-    return true;
-  }
-
-  if (strcmp(name, "mdpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_MEDIUM;
-    return true;
-  }
-
-  if (strcmp(name, "tvdpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_TV;
-    return true;
-  }
-
-  if (strcmp(name, "hdpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_HIGH;
-    return true;
-  }
-
-  if (strcmp(name, "xhdpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_XHIGH;
-    return true;
-  }
-
-  if (strcmp(name, "xxhdpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_XXHIGH;
-    return true;
-  }
-
-  if (strcmp(name, "xxxhdpi") == 0) {
-    if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
-    return true;
-  }
-
-  char* c = (char*)name;
-  while (*c >= '0' && *c <= '9') {
-    c++;
-  }
-
-  // check that we have 'dpi' after the last digit.
-  if (toupper(c[0]) != 'D' || toupper(c[1]) != 'P' || toupper(c[2]) != 'I' ||
-      c[3] != 0) {
-    return false;
-  }
-
-  // temporarily replace the first letter with \0 to
-  // use atoi.
-  char tmp = c[0];
-  c[0] = '\0';
-
-  int d = atoi(name);
-  c[0] = tmp;
-
-  if (d != 0) {
-    if (out) out->density = d;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseTouchscreen(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
-    return true;
-  } else if (strcmp(name, "notouch") == 0) {
-    if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
-    return true;
-  } else if (strcmp(name, "stylus") == 0) {
-    if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
-    return true;
-  } else if (strcmp(name, "finger") == 0) {
-    if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseKeysHidden(const char* name, ResTable_config* out) {
-  uint8_t mask = 0;
-  uint8_t value = 0;
-  if (strcmp(name, kWildcardName) == 0) {
-    mask = ResTable_config::MASK_KEYSHIDDEN;
-    value = ResTable_config::KEYSHIDDEN_ANY;
-  } else if (strcmp(name, "keysexposed") == 0) {
-    mask = ResTable_config::MASK_KEYSHIDDEN;
-    value = ResTable_config::KEYSHIDDEN_NO;
-  } else if (strcmp(name, "keyshidden") == 0) {
-    mask = ResTable_config::MASK_KEYSHIDDEN;
-    value = ResTable_config::KEYSHIDDEN_YES;
-  } else if (strcmp(name, "keyssoft") == 0) {
-    mask = ResTable_config::MASK_KEYSHIDDEN;
-    value = ResTable_config::KEYSHIDDEN_SOFT;
-  }
-
-  if (mask != 0) {
-    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseKeyboard(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->keyboard = out->KEYBOARD_ANY;
-    return true;
-  } else if (strcmp(name, "nokeys") == 0) {
-    if (out) out->keyboard = out->KEYBOARD_NOKEYS;
-    return true;
-  } else if (strcmp(name, "qwerty") == 0) {
-    if (out) out->keyboard = out->KEYBOARD_QWERTY;
-    return true;
-  } else if (strcmp(name, "12key") == 0) {
-    if (out) out->keyboard = out->KEYBOARD_12KEY;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseNavHidden(const char* name, ResTable_config* out) {
-  uint8_t mask = 0;
-  uint8_t value = 0;
-  if (strcmp(name, kWildcardName) == 0) {
-    mask = ResTable_config::MASK_NAVHIDDEN;
-    value = ResTable_config::NAVHIDDEN_ANY;
-  } else if (strcmp(name, "navexposed") == 0) {
-    mask = ResTable_config::MASK_NAVHIDDEN;
-    value = ResTable_config::NAVHIDDEN_NO;
-  } else if (strcmp(name, "navhidden") == 0) {
-    mask = ResTable_config::MASK_NAVHIDDEN;
-    value = ResTable_config::NAVHIDDEN_YES;
-  }
-
-  if (mask != 0) {
-    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseNavigation(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) out->navigation = out->NAVIGATION_ANY;
-    return true;
-  } else if (strcmp(name, "nonav") == 0) {
-    if (out) out->navigation = out->NAVIGATION_NONAV;
-    return true;
-  } else if (strcmp(name, "dpad") == 0) {
-    if (out) out->navigation = out->NAVIGATION_DPAD;
-    return true;
-  } else if (strcmp(name, "trackball") == 0) {
-    if (out) out->navigation = out->NAVIGATION_TRACKBALL;
-    return true;
-  } else if (strcmp(name, "wheel") == 0) {
-    if (out) out->navigation = out->NAVIGATION_WHEEL;
-    return true;
-  }
-
-  return false;
-}
-
-static bool parseScreenSize(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) {
-      out->screenWidth = out->SCREENWIDTH_ANY;
-      out->screenHeight = out->SCREENHEIGHT_ANY;
-    }
-    return true;
-  }
-
-  const char* x = name;
-  while (*x >= '0' && *x <= '9') x++;
-  if (x == name || *x != 'x') return false;
-  std::string xName(name, x - name);
-  x++;
-
-  const char* y = x;
-  while (*y >= '0' && *y <= '9') y++;
-  if (y == name || *y != 0) return false;
-  std::string yName(x, y - x);
-
-  uint16_t w = (uint16_t)atoi(xName.c_str());
-  uint16_t h = (uint16_t)atoi(yName.c_str());
-  if (w < h) {
-    return false;
-  }
-
-  if (out) {
-    out->screenWidth = w;
-    out->screenHeight = h;
-  }
-
-  return true;
-}
-
-static bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) {
-      out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
-    }
-    return true;
-  }
-
-  if (*name != 's') return false;
-  name++;
-  if (*name != 'w') return false;
-  name++;
-  const char* x = name;
-  while (*x >= '0' && *x <= '9') x++;
-  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
-  std::string xName(name, x - name);
-
-  if (out) {
-    out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
-  }
-
-  return true;
-}
-
-static bool parseScreenWidthDp(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) {
-      out->screenWidthDp = out->SCREENWIDTH_ANY;
-    }
-    return true;
-  }
-
-  if (*name != 'w') return false;
-  name++;
-  const char* x = name;
-  while (*x >= '0' && *x <= '9') x++;
-  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
-  std::string xName(name, x - name);
-
-  if (out) {
-    out->screenWidthDp = (uint16_t)atoi(xName.c_str());
-  }
-
-  return true;
-}
-
-static bool parseScreenHeightDp(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) {
-      out->screenHeightDp = out->SCREENWIDTH_ANY;
-    }
-    return true;
-  }
-
-  if (*name != 'h') return false;
-  name++;
-  const char* x = name;
-  while (*x >= '0' && *x <= '9') x++;
-  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
-  std::string xName(name, x - name);
-
-  if (out) {
-    out->screenHeightDp = (uint16_t)atoi(xName.c_str());
-  }
-
-  return true;
-}
-
-static bool parseVersion(const char* name, ResTable_config* out) {
-  if (strcmp(name, kWildcardName) == 0) {
-    if (out) {
-      out->sdkVersion = out->SDKVERSION_ANY;
-      out->minorVersion = out->MINORVERSION_ANY;
-    }
-    return true;
-  }
-
-  if (*name != 'v') {
-    return false;
-  }
-
-  name++;
-  const char* s = name;
-  while (*s >= '0' && *s <= '9') s++;
-  if (s == name || *s != 0) return false;
-  std::string sdkName(name, s - name);
-
-  if (out) {
-    out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
-    out->minorVersion = 0;
-  }
-
-  return true;
-}
-
-bool ConfigDescription::Parse(const StringPiece& str, ConfigDescription* out) {
-  std::vector<std::string> parts = util::SplitAndLowercase(str, '-');
-
-  ConfigDescription config;
-  ssize_t parts_consumed = 0;
-  LocaleValue locale;
-
-  const auto parts_end = parts.end();
-  auto part_iter = parts.begin();
-
-  if (str.size() == 0) {
-    goto success;
-  }
-
-  if (parseMcc(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseMnc(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  // Locale spans a few '-' separators, so we let it
-  // control the index.
-  parts_consumed = locale.InitFromParts(part_iter, parts_end);
-  if (parts_consumed < 0) {
-    return false;
-  } else {
-    locale.WriteTo(&config);
-    part_iter += parts_consumed;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseLayoutDirection(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseScreenWidthDp(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseScreenHeightDp(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseScreenLayoutSize(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseScreenLayoutLong(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseScreenRound(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseWideColorGamut(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseHdr(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseOrientation(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseUiModeType(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseUiModeNight(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseDensity(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseTouchscreen(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseKeysHidden(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseKeyboard(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseNavHidden(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseNavigation(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseScreenSize(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  if (parseVersion(part_iter->c_str(), &config)) {
-    ++part_iter;
-    if (part_iter == parts_end) {
-      goto success;
-    }
-  }
-
-  // Unrecognized.
-  return false;
-
-success:
-  if (out != NULL) {
-    ApplyVersionForCompatibility(&config);
-    *out = config;
-  }
-  return true;
-}
-
-void ConfigDescription::ApplyVersionForCompatibility(
-    ConfigDescription* config) {
-  uint16_t min_sdk = 0;
-  if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
-                == ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
-            config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT ||
-            config->colorMode & ResTable_config::MASK_HDR) {
-        min_sdk = SDK_O;
-  } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
-    min_sdk = SDK_MARSHMALLOW;
-  } else if (config->density == ResTable_config::DENSITY_ANY) {
-    min_sdk = SDK_LOLLIPOP;
-  } else if (config->smallestScreenWidthDp !=
-                 ResTable_config::SCREENWIDTH_ANY ||
-             config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
-             config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
-    min_sdk = SDK_HONEYCOMB_MR2;
-  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) !=
-                 ResTable_config::UI_MODE_TYPE_ANY ||
-             (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) !=
-                 ResTable_config::UI_MODE_NIGHT_ANY) {
-    min_sdk = SDK_FROYO;
-  } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) !=
-                 ResTable_config::SCREENSIZE_ANY ||
-             (config->screenLayout & ResTable_config::MASK_SCREENLONG) !=
-                 ResTable_config::SCREENLONG_ANY ||
-             config->density != ResTable_config::DENSITY_DEFAULT) {
-    min_sdk = SDK_DONUT;
-  }
-
-  if (min_sdk > config->sdkVersion) {
-    config->sdkVersion = min_sdk;
-  }
-}
-
-ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
-  ConfigDescription copy = *this;
-  copy.sdkVersion = 0;
-  return copy;
-}
-
-std::string ConfigDescription::GetBcp47LanguageTag(bool canonicalize) const {
-  char locale[RESTABLE_MAX_LOCALE_LEN];
-  getBcp47Locale(locale, canonicalize);
-  return std::string(locale);
-}
-
-std::string ConfigDescription::to_string() const {
-  const android::String8 str = toString();
-  return std::string(str.string(), str.size());
-}
-
-bool ConfigDescription::Dominates(const ConfigDescription& o) const {
-  if (*this == o) {
-    return true;
-  }
-
-  // Locale de-duping is not-trivial, disable for now (b/62409213).
-  if (diff(o) & CONFIG_LOCALE) {
-    return false;
-  }
-
-  if (*this == DefaultConfig()) {
-    return true;
-  }
-  return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
-         !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this);
-}
-
-bool ConfigDescription::HasHigherPrecedenceThan(
-    const ConfigDescription& o) const {
-  // The order of the following tests defines the importance of one
-  // configuration parameter over another. Those tests first are more
-  // important, trumping any values in those following them.
-  // The ordering should be the same as ResTable_config#isBetterThan.
-  if (mcc || o.mcc) return (!o.mcc);
-  if (mnc || o.mnc) return (!o.mnc);
-  if (language[0] || o.language[0]) return (!o.language[0]);
-  if (country[0] || o.country[0]) return (!o.country[0]);
-  // Script and variant require either a language or country, both of which
-  // have higher precedence.
-  if ((screenLayout | o.screenLayout) & MASK_LAYOUTDIR) {
-    return !(o.screenLayout & MASK_LAYOUTDIR);
-  }
-  if (smallestScreenWidthDp || o.smallestScreenWidthDp)
-    return (!o.smallestScreenWidthDp);
-  if (screenWidthDp || o.screenWidthDp) return (!o.screenWidthDp);
-  if (screenHeightDp || o.screenHeightDp) return (!o.screenHeightDp);
-  if ((screenLayout | o.screenLayout) & MASK_SCREENSIZE) {
-    return !(o.screenLayout & MASK_SCREENSIZE);
-  }
-  if ((screenLayout | o.screenLayout) & MASK_SCREENLONG) {
-    return !(o.screenLayout & MASK_SCREENLONG);
-  }
-  if ((screenLayout2 | o.screenLayout2) & MASK_SCREENROUND) {
-    return !(o.screenLayout2 & MASK_SCREENROUND);
-  }
-  if ((colorMode | o.colorMode) & MASK_HDR) {
-    return !(o.colorMode & MASK_HDR);
-  }
-  if ((colorMode | o.colorMode) & MASK_WIDE_COLOR_GAMUT) {
-    return !(o.colorMode & MASK_WIDE_COLOR_GAMUT);
-  }
-  if (orientation || o.orientation) return (!o.orientation);
-  if ((uiMode | o.uiMode) & MASK_UI_MODE_TYPE) {
-    return !(o.uiMode & MASK_UI_MODE_TYPE);
-  }
-  if ((uiMode | o.uiMode) & MASK_UI_MODE_NIGHT) {
-    return !(o.uiMode & MASK_UI_MODE_NIGHT);
-  }
-  if (density || o.density) return (!o.density);
-  if (touchscreen || o.touchscreen) return (!o.touchscreen);
-  if ((inputFlags | o.inputFlags) & MASK_KEYSHIDDEN) {
-    return !(o.inputFlags & MASK_KEYSHIDDEN);
-  }
-  if ((inputFlags | o.inputFlags) & MASK_NAVHIDDEN) {
-    return !(o.inputFlags & MASK_NAVHIDDEN);
-  }
-  if (keyboard || o.keyboard) return (!o.keyboard);
-  if (navigation || o.navigation) return (!o.navigation);
-  if (screenWidth || o.screenWidth) return (!o.screenWidth);
-  if (screenHeight || o.screenHeight) return (!o.screenHeight);
-  if (sdkVersion || o.sdkVersion) return (!o.sdkVersion);
-  if (minorVersion || o.minorVersion) return (!o.minorVersion);
-  // Both configurations have nothing defined except some possible future
-  // value. Returning the comparison of the two configurations is a
-  // "best effort" at this point to protect against incorrect dominations.
-  return *this != o;
-}
-
-bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const {
-  // This method should be updated as new configuration parameters are
-  // introduced (e.g. screenConfig2).
-  auto pred = [](const uint32_t a, const uint32_t b) -> bool {
-    return a == 0 || b == 0 || a == b;
-  };
-  // The values here can be found in ResTable_config#match. Density and range
-  // values can't lead to conflicts, and are ignored.
-  return !pred(mcc, o.mcc) || !pred(mnc, o.mnc) || !pred(locale, o.locale) ||
-         !pred(screenLayout & MASK_LAYOUTDIR,
-               o.screenLayout & MASK_LAYOUTDIR) ||
-         !pred(screenLayout & MASK_SCREENLONG,
-               o.screenLayout & MASK_SCREENLONG) ||
-         !pred(uiMode & MASK_UI_MODE_TYPE, o.uiMode & MASK_UI_MODE_TYPE) ||
-         !pred(uiMode & MASK_UI_MODE_NIGHT, o.uiMode & MASK_UI_MODE_NIGHT) ||
-         !pred(screenLayout2 & MASK_SCREENROUND,
-               o.screenLayout2 & MASK_SCREENROUND) ||
-         !pred(colorMode & MASK_HDR, o.colorMode & MASK_HDR) ||
-         !pred(colorMode & MASK_WIDE_COLOR_GAMUT,
-               o.colorMode & MASK_WIDE_COLOR_GAMUT) ||
-         !pred(orientation, o.orientation) ||
-         !pred(touchscreen, o.touchscreen) ||
-         !pred(inputFlags & MASK_KEYSHIDDEN, o.inputFlags & MASK_KEYSHIDDEN) ||
-         !pred(inputFlags & MASK_NAVHIDDEN, o.inputFlags & MASK_NAVHIDDEN) ||
-         !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation);
-}
-
-bool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const {
-  return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
-}
-
-}  // namespace aapt
diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h
deleted file mode 100644
index f719552..0000000
--- a/tools/aapt2/ConfigDescription.h
+++ /dev/null
@@ -1,185 +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 AAPT_CONFIG_DESCRIPTION_H
-#define AAPT_CONFIG_DESCRIPTION_H
-
-#include <ostream>
-
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/StringPiece.h"
-
-namespace aapt {
-
-/*
- * Subclass of ResTable_config that adds convenient
- * initialization and comparison methods.
- */
-struct ConfigDescription : public android::ResTable_config {
-  /**
-   * Returns an immutable default config.
-   */
-  static const ConfigDescription& DefaultConfig();
-
-  /*
-   * Parse a string of the form 'fr-sw600dp-land' and fill in the
-   * given ResTable_config with resulting configuration parameters.
-   *
-   * The resulting configuration has the appropriate sdkVersion defined
-   * for backwards compatibility.
-   */
-  static bool Parse(const android::StringPiece& str, ConfigDescription* out = nullptr);
-
-  /**
-   * If the configuration uses an axis that was added after
-   * the original Android release, make sure the SDK version
-   * is set accordingly.
-   */
-  static void ApplyVersionForCompatibility(ConfigDescription* config);
-
-  ConfigDescription();
-  ConfigDescription(const android::ResTable_config& o);  // NOLINT(implicit)
-  ConfigDescription(const ConfigDescription& o);
-  ConfigDescription(ConfigDescription&& o);
-
-  ConfigDescription& operator=(const android::ResTable_config& o);
-  ConfigDescription& operator=(const ConfigDescription& o);
-  ConfigDescription& operator=(ConfigDescription&& o);
-
-  ConfigDescription CopyWithoutSdkVersion() const;
-
-  // Returns the BCP-47 language tag of this configuration's locale.
-  std::string GetBcp47LanguageTag(bool canonicalize = false) const;
-
-  std::string to_string() const;
-
-  /**
-   * A configuration X dominates another configuration Y, if X has at least the
-   * precedence of Y and X is strictly more general than Y: for any type defined
-   * by X, the same type is defined by Y with a value equal to or, in the case
-   * of ranges, more specific than that of X.
-   *
-   * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It
-   * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'.
-   */
-  bool Dominates(const ConfigDescription& o) const;
-
-  /**
-   * Returns true if this configuration defines a more important configuration
-   * parameter than o. For example, "en" has higher precedence than "v23",
-   * whereas "en" has the same precedence as "en-v23".
-   */
-  bool HasHigherPrecedenceThan(const ConfigDescription& o) const;
-
-  /**
-   * A configuration conflicts with another configuration if both
-   * configurations define an incompatible configuration parameter. An
-   * incompatible configuration parameter is a non-range, non-density parameter
-   * that is defined in both configurations as a different, non-default value.
-   */
-  bool ConflictsWith(const ConfigDescription& o) const;
-
-  /**
-   * A configuration is compatible with another configuration if both
-   * configurations can match a common concrete device configuration and are
-   * unrelated by domination. For example, land-v11 conflicts with port-v21
-   * but is compatible with v21 (both land-v11 and v21 would match en-land-v23).
-   */
-  bool IsCompatibleWith(const ConfigDescription& o) const;
-
-  bool MatchWithDensity(const ConfigDescription& o) const;
-
-  bool operator<(const ConfigDescription& o) const;
-  bool operator<=(const ConfigDescription& o) const;
-  bool operator==(const ConfigDescription& o) const;
-  bool operator!=(const ConfigDescription& o) const;
-  bool operator>=(const ConfigDescription& o) const;
-  bool operator>(const ConfigDescription& o) const;
-};
-
-inline ConfigDescription::ConfigDescription() {
-  memset(this, 0, sizeof(*this));
-  size = sizeof(android::ResTable_config);
-}
-
-inline ConfigDescription::ConfigDescription(const android::ResTable_config& o) {
-  *static_cast<android::ResTable_config*>(this) = o;
-  size = sizeof(android::ResTable_config);
-}
-
-inline ConfigDescription::ConfigDescription(const ConfigDescription& o) {
-  *static_cast<android::ResTable_config*>(this) = o;
-}
-
-inline ConfigDescription::ConfigDescription(ConfigDescription&& o) {
-  *this = o;
-}
-
-inline ConfigDescription& ConfigDescription::operator=(
-    const android::ResTable_config& o) {
-  *static_cast<android::ResTable_config*>(this) = o;
-  size = sizeof(android::ResTable_config);
-  return *this;
-}
-
-inline ConfigDescription& ConfigDescription::operator=(
-    const ConfigDescription& o) {
-  *static_cast<android::ResTable_config*>(this) = o;
-  return *this;
-}
-
-inline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) {
-  *this = o;
-  return *this;
-}
-
-inline bool ConfigDescription::MatchWithDensity(
-    const ConfigDescription& o) const {
-  return match(o) && (density == 0 || density == o.density);
-}
-
-inline bool ConfigDescription::operator<(const ConfigDescription& o) const {
-  return compare(o) < 0;
-}
-
-inline bool ConfigDescription::operator<=(const ConfigDescription& o) const {
-  return compare(o) <= 0;
-}
-
-inline bool ConfigDescription::operator==(const ConfigDescription& o) const {
-  return compare(o) == 0;
-}
-
-inline bool ConfigDescription::operator!=(const ConfigDescription& o) const {
-  return compare(o) != 0;
-}
-
-inline bool ConfigDescription::operator>=(const ConfigDescription& o) const {
-  return compare(o) >= 0;
-}
-
-inline bool ConfigDescription::operator>(const ConfigDescription& o) const {
-  return compare(o) > 0;
-}
-
-inline ::std::ostream& operator<<(::std::ostream& out,
-                                  const ConfigDescription& o) {
-  return out << o.toString().string();
-}
-
-}  // namespace aapt
-
-#endif  // AAPT_CONFIG_DESCRIPTION_H
diff --git a/tools/aapt2/ConfigDescription_test.cpp b/tools/aapt2/ConfigDescription_test.cpp
deleted file mode 100644
index 1f351bf..0000000
--- a/tools/aapt2/ConfigDescription_test.cpp
+++ /dev/null
@@ -1,155 +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 "ConfigDescription.h"
-
-#include <string>
-
-#include "androidfw/StringPiece.h"
-
-#include "SdkConstants.h"
-#include "test/Test.h"
-
-using android::StringPiece;
-
-namespace aapt {
-
-static ::testing::AssertionResult TestParse(
-    const StringPiece& input, ConfigDescription* config = nullptr) {
-  if (ConfigDescription::Parse(input, config)) {
-    return ::testing::AssertionSuccess() << input << " was successfully parsed";
-  }
-  return ::testing::AssertionFailure() << input << " could not be parsed";
-}
-
-TEST(ConfigDescriptionTest, ParseFailWhenQualifiersAreOutOfOrder) {
-  EXPECT_FALSE(TestParse("en-sw600dp-ldrtl"));
-  EXPECT_FALSE(TestParse("land-en"));
-  EXPECT_FALSE(TestParse("hdpi-320dpi"));
-}
-
-TEST(ConfigDescriptionTest, ParseFailWhenQualifiersAreNotMatched) {
-  EXPECT_FALSE(TestParse("en-sw600dp-ILLEGAL"));
-}
-
-TEST(ConfigDescriptionTest, ParseFailWhenQualifiersHaveTrailingDash) {
-  EXPECT_FALSE(TestParse("en-sw600dp-land-"));
-}
-
-TEST(ConfigDescriptionTest, ParseBasicQualifiers) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("", &config));
-  EXPECT_EQ(std::string(""), config.toString().string());
-
-  EXPECT_TRUE(TestParse("fr-land", &config));
-  EXPECT_EQ(std::string("fr-land"), config.toString().string());
-
-  EXPECT_TRUE(
-      TestParse("mcc310-pl-sw720dp-normal-long-port-night-"
-                "xhdpi-keyssoft-qwerty-navexposed-nonav",
-                &config));
-  EXPECT_EQ(std::string("mcc310-pl-sw720dp-normal-long-port-night-"
-                        "xhdpi-keyssoft-qwerty-navexposed-nonav-v13"),
-            config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, ParseLocales) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("en-rUS", &config));
-  EXPECT_EQ(std::string("en-rUS"), config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, ParseQualifierAddedInApi13) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("sw600dp", &config));
-  EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
-
-  EXPECT_TRUE(TestParse("sw600dp-v8", &config));
-  EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, ParseCarAttribute) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("car", &config));
-  EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_CAR, config.uiMode);
-}
-
-TEST(ConfigDescriptionTest, TestParsingRoundQualifier) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("round", &config));
-  EXPECT_EQ(android::ResTable_config::SCREENROUND_YES,
-            config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);
-  EXPECT_EQ(SDK_MARSHMALLOW, config.sdkVersion);
-  EXPECT_EQ(std::string("round-v23"), config.toString().string());
-
-  EXPECT_TRUE(TestParse("notround", &config));
-  EXPECT_EQ(android::ResTable_config::SCREENROUND_NO,
-            config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);
-  EXPECT_EQ(SDK_MARSHMALLOW, config.sdkVersion);
-  EXPECT_EQ(std::string("notround-v23"), config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, TestWideColorGamutQualifier) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("widecg", &config));
-  EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_YES,
-            config.colorMode & android::ResTable_config::MASK_WIDE_COLOR_GAMUT);
-  EXPECT_EQ(SDK_O, config.sdkVersion);
-  EXPECT_EQ(std::string("widecg-v26"), config.toString().string());
-
-  EXPECT_TRUE(TestParse("nowidecg", &config));
-  EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_NO,
-            config.colorMode & android::ResTable_config::MASK_WIDE_COLOR_GAMUT);
-  EXPECT_EQ(SDK_O, config.sdkVersion);
-  EXPECT_EQ(std::string("nowidecg-v26"), config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, TestHdrQualifier) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("highdr", &config));
-  EXPECT_EQ(android::ResTable_config::HDR_YES,
-            config.colorMode & android::ResTable_config::MASK_HDR);
-  EXPECT_EQ(SDK_O, config.sdkVersion);
-  EXPECT_EQ(std::string("highdr-v26"), config.toString().string());
-
-  EXPECT_TRUE(TestParse("lowdr", &config));
-  EXPECT_EQ(android::ResTable_config::HDR_NO,
-            config.colorMode & android::ResTable_config::MASK_HDR);
-  EXPECT_EQ(SDK_O, config.sdkVersion);
-  EXPECT_EQ(std::string("lowdr-v26"), config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, ParseVrAttribute) {
-  ConfigDescription config;
-  EXPECT_TRUE(TestParse("vrheadset", &config));
-  EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_VR_HEADSET, config.uiMode);
-  EXPECT_EQ(SDK_O, config.sdkVersion);
-  EXPECT_EQ(std::string("vrheadset-v26"), config.toString().string());
-}
-
-TEST(ConfigDescriptionTest, RangeQualifiersDoNotConflict) {
-  using test::ParseConfigOrDie;
-
-  EXPECT_FALSE(ParseConfigOrDie("large").ConflictsWith(ParseConfigOrDie("normal-land")));
-  EXPECT_FALSE(ParseConfigOrDie("long-hdpi").ConflictsWith(ParseConfigOrDie("xhdpi")));
-  EXPECT_FALSE(ParseConfigOrDie("sw600dp").ConflictsWith(ParseConfigOrDie("sw700dp")));
-  EXPECT_FALSE(ParseConfigOrDie("v11").ConflictsWith(ParseConfigOrDie("v21")));
-  EXPECT_FALSE(ParseConfigOrDie("h600dp").ConflictsWith(ParseConfigOrDie("h300dp")));
-  EXPECT_FALSE(ParseConfigOrDie("w400dp").ConflictsWith(ParseConfigOrDie("w300dp")));
-  EXPECT_FALSE(ParseConfigOrDie("600x400").ConflictsWith(ParseConfigOrDie("300x200")));
-}
-
-}  // namespace aapt
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 6d78990..a20b9b7 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -69,8 +69,8 @@
       return {};
     }
 
-    io::ZeroCopyInputAdaptor adaptor(in.get());
-    if (!pb_table.ParseFromZeroCopyStream(&adaptor)) {
+    io::ProtoInputStreamReader proto_reader(in.get());
+    if (!proto_reader.ReadMessage(&pb_table)) {
       diag->Error(DiagMessage(source) << "failed to read " << kProtoResourceTablePath);
       return {};
     }
@@ -97,8 +97,8 @@
   }
 
   pb::XmlNode pb_node;
-  io::ZeroCopyInputAdaptor manifest_adaptor(manifest_in.get());
-  if (!pb_node.ParseFromZeroCopyStream(&manifest_adaptor)) {
+  io::ProtoInputStreamReader proto_reader(manifest_in.get());
+  if (!proto_reader.ReadMessage(&pb_node)) {
     diag->Error(DiagMessage(source) << "failed to read proto " << kAndroidManifestPath);
     return {};
   }
@@ -270,9 +270,9 @@
       return nullptr;
     }
 
-    io::ZeroCopyInputAdaptor adaptor(in.get());
     pb::XmlNode pb_node;
-    if (!pb_node.ParseFromZeroCopyStream(&adaptor)) {
+    io::ProtoInputStreamReader proto_reader(in.get());
+    if (!proto_reader.ReadMessage(&pb_node)) {
       diag->Error(DiagMessage() << "failed to parse file as proto XML");
       return nullptr;
     }
@@ -317,8 +317,8 @@
     std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream();
     if (manifest_in != nullptr) {
       pb::XmlNode pb_node;
-      io::ZeroCopyInputAdaptor manifest_adaptor(manifest_in.get());
-      if (pb_node.ParseFromZeroCopyStream(&manifest_adaptor)) {
+      io::ProtoInputStreamReader proto_reader(manifest_in.get());
+      if (!proto_reader.ReadMessage(&pb_node)) {
         return ApkFormat::kProto;
       }
     }
diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp
deleted file mode 100644
index d81921f..0000000
--- a/tools/aapt2/Locale.cpp
+++ /dev/null
@@ -1,261 +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 "Locale.h"
-
-#include <ctype.h>
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "util/Util.h"
-
-using ::android::ResTable_config;
-using ::android::StringPiece;
-
-namespace aapt {
-
-void LocaleValue::set_language(const char* language_chars) {
-  size_t i = 0;
-  while ((*language_chars) != '\0') {
-    language[i++] = ::tolower(*language_chars);
-    language_chars++;
-  }
-}
-
-void LocaleValue::set_region(const char* region_chars) {
-  size_t i = 0;
-  while ((*region_chars) != '\0') {
-    region[i++] = ::toupper(*region_chars);
-    region_chars++;
-  }
-}
-
-void LocaleValue::set_script(const char* script_chars) {
-  size_t i = 0;
-  while ((*script_chars) != '\0') {
-    if (i == 0) {
-      script[i++] = ::toupper(*script_chars);
-    } else {
-      script[i++] = ::tolower(*script_chars);
-    }
-    script_chars++;
-  }
-}
-
-void LocaleValue::set_variant(const char* variant_chars) {
-  size_t i = 0;
-  while ((*variant_chars) != '\0') {
-    variant[i++] = *variant_chars;
-    variant_chars++;
-  }
-}
-
-static inline bool is_alpha(const std::string& str) {
-  return std::all_of(std::begin(str), std::end(str), ::isalpha);
-}
-
-static inline bool is_number(const std::string& str) {
-  return std::all_of(std::begin(str), std::end(str), ::isdigit);
-}
-
-bool LocaleValue::InitFromFilterString(const StringPiece& str) {
-  // A locale (as specified in the filter) is an underscore separated name such
-  // as "en_US", "en_Latn_US", or "en_US_POSIX".
-  std::vector<std::string> parts = util::SplitAndLowercase(str, '_');
-
-  const int num_tags = parts.size();
-  bool valid = false;
-  if (num_tags >= 1) {
-    const std::string& lang = parts[0];
-    if (is_alpha(lang) && (lang.length() == 2 || lang.length() == 3)) {
-      set_language(lang.c_str());
-      valid = true;
-    }
-  }
-
-  if (!valid || num_tags == 1) {
-    return valid;
-  }
-
-  // At this point, valid == true && numTags > 1.
-  const std::string& part2 = parts[1];
-  if ((part2.length() == 2 && is_alpha(part2)) ||
-      (part2.length() == 3 && is_number(part2))) {
-    set_region(part2.c_str());
-  } else if (part2.length() == 4 && is_alpha(part2)) {
-    set_script(part2.c_str());
-  } else if (part2.length() >= 4 && part2.length() <= 8) {
-    set_variant(part2.c_str());
-  } else {
-    valid = false;
-  }
-
-  if (!valid || num_tags == 2) {
-    return valid;
-  }
-
-  // At this point, valid == true && numTags > 1.
-  const std::string& part3 = parts[2];
-  if (((part3.length() == 2 && is_alpha(part3)) ||
-       (part3.length() == 3 && is_number(part3))) &&
-      script[0]) {
-    set_region(part3.c_str());
-  } else if (part3.length() >= 4 && part3.length() <= 8) {
-    set_variant(part3.c_str());
-  } else {
-    valid = false;
-  }
-
-  if (!valid || num_tags == 3) {
-    return valid;
-  }
-
-  const std::string& part4 = parts[3];
-  if (part4.length() >= 4 && part4.length() <= 8) {
-    set_variant(part4.c_str());
-  } else {
-    valid = false;
-  }
-
-  if (!valid || num_tags > 4) {
-    return false;
-  }
-
-  return true;
-}
-
-bool LocaleValue::InitFromBcp47Tag(const StringPiece& bcp47tag) {
-  return InitFromBcp47TagImpl(bcp47tag, '-');
-}
-
-bool LocaleValue::InitFromBcp47TagImpl(const StringPiece& bcp47tag, const char separator) {
-  std::vector<std::string> subtags = util::SplitAndLowercase(bcp47tag, separator);
-  if (subtags.size() == 1) {
-    set_language(subtags[0].c_str());
-  } else if (subtags.size() == 2) {
-    set_language(subtags[0].c_str());
-
-    // The second tag can either be a region, a variant or a script.
-    switch (subtags[1].size()) {
-      case 2:
-      case 3:
-        set_region(subtags[1].c_str());
-        break;
-      case 4:
-        if ('0' <= subtags[1][0] && subtags[1][0] <= '9') {
-          // This is a variant: fall through
-        } else {
-          set_script(subtags[1].c_str());
-          break;
-        }
-      case 5:
-      case 6:
-      case 7:
-      case 8:
-        set_variant(subtags[1].c_str());
-        break;
-      default:
-        return false;
-    }
-  } else if (subtags.size() == 3) {
-    // The language is always the first subtag.
-    set_language(subtags[0].c_str());
-
-    // The second subtag can either be a script or a region code.
-    // If its size is 4, it's a script code, else it's a region code.
-    if (subtags[1].size() == 4) {
-      set_script(subtags[1].c_str());
-    } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
-      set_region(subtags[1].c_str());
-    } else {
-      return false;
-    }
-
-    // The third tag can either be a region code (if the second tag was
-    // a script), else a variant code.
-    if (subtags[2].size() >= 4) {
-      set_variant(subtags[2].c_str());
-    } else {
-      set_region(subtags[2].c_str());
-    }
-  } else if (subtags.size() == 4) {
-    set_language(subtags[0].c_str());
-    set_script(subtags[1].c_str());
-    set_region(subtags[2].c_str());
-    set_variant(subtags[3].c_str());
-  } else {
-    return false;
-  }
-  return true;
-}
-
-ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
-                                   std::vector<std::string>::iterator end) {
-  const std::vector<std::string>::iterator start_iter = iter;
-
-  std::string& part = *iter;
-  if (part[0] == 'b' && part[1] == '+') {
-    // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags,
-    // except that the separator is "+" and not "-". Skip the prefix 'b+'.
-    if (!InitFromBcp47TagImpl(StringPiece(part).substr(2), '+')) {
-      return -1;
-    }
-    ++iter;
-  } else {
-    if ((part.length() == 2 || part.length() == 3) && is_alpha(part) && part != "car") {
-      set_language(part.c_str());
-      ++iter;
-
-      if (iter != end) {
-        const std::string& region_part = *iter;
-        if (region_part.c_str()[0] == 'r' && region_part.length() == 3) {
-          set_region(region_part.c_str() + 1);
-          ++iter;
-        }
-      }
-    }
-  }
-  return static_cast<ssize_t>(iter - start_iter);
-}
-
-void LocaleValue::InitFromResTable(const ResTable_config& config) {
-  config.unpackLanguage(language);
-  config.unpackRegion(region);
-  if (config.localeScript[0] && !config.localeScriptWasComputed) {
-    memcpy(script, config.localeScript, sizeof(config.localeScript));
-  }
-
-  if (config.localeVariant[0]) {
-    memcpy(variant, config.localeVariant, sizeof(config.localeVariant));
-  }
-}
-
-void LocaleValue::WriteTo(ResTable_config* out) const {
-  out->packLanguage(language);
-  out->packRegion(region);
-
-  if (script[0]) {
-    memcpy(out->localeScript, script, sizeof(out->localeScript));
-  }
-
-  if (variant[0]) {
-    memcpy(out->localeVariant, variant, sizeof(out->localeVariant));
-  }
-}
-
-}  // namespace aapt
diff --git a/tools/aapt2/Locale.h b/tools/aapt2/Locale.h
deleted file mode 100644
index 6d8b598..0000000
--- a/tools/aapt2/Locale.h
+++ /dev/null
@@ -1,117 +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 AAPT_LOCALE_VALUE_H
-#define AAPT_LOCALE_VALUE_H
-
-#include <string>
-#include <vector>
-
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/StringPiece.h"
-
-namespace aapt {
-
-/**
- * A convenience class to build and parse locales.
- */
-struct LocaleValue {
-  char language[4];
-  char region[4];
-  char script[4];
-  char variant[8];
-
-  inline LocaleValue();
-
-  /**
-   * Initialize this LocaleValue from a config string.
-   */
-  bool InitFromFilterString(const android::StringPiece& config);
-
-  // Initializes this LocaleValue from a BCP-47 locale tag.
-  bool InitFromBcp47Tag(const android::StringPiece& bcp47tag);
-
-  /**
-   * Initialize this LocaleValue from parts of a vector.
-   */
-  ssize_t InitFromParts(std::vector<std::string>::iterator iter,
-                        std::vector<std::string>::iterator end);
-
-  /**
-   * Initialize this LocaleValue from a ResTable_config.
-   */
-  void InitFromResTable(const android::ResTable_config& config);
-
-  /**
-   * Set the locale in a ResTable_config from this LocaleValue.
-   */
-  void WriteTo(android::ResTable_config* out) const;
-
-  inline int compare(const LocaleValue& other) const;
-
-  inline bool operator<(const LocaleValue& o) const;
-  inline bool operator<=(const LocaleValue& o) const;
-  inline bool operator==(const LocaleValue& o) const;
-  inline bool operator!=(const LocaleValue& o) const;
-  inline bool operator>=(const LocaleValue& o) const;
-  inline bool operator>(const LocaleValue& o) const;
-
- private:
-  bool InitFromBcp47TagImpl(const android::StringPiece& bcp47tag, const char separator);
-
-  void set_language(const char* language);
-  void set_region(const char* language);
-  void set_script(const char* script);
-  void set_variant(const char* variant);
-};
-
-//
-// Implementation
-//
-
-LocaleValue::LocaleValue() { memset(this, 0, sizeof(LocaleValue)); }
-
-int LocaleValue::compare(const LocaleValue& other) const {
-  return memcmp(this, &other, sizeof(LocaleValue));
-}
-
-bool LocaleValue::operator<(const LocaleValue& o) const {
-  return compare(o) < 0;
-}
-
-bool LocaleValue::operator<=(const LocaleValue& o) const {
-  return compare(o) <= 0;
-}
-
-bool LocaleValue::operator==(const LocaleValue& o) const {
-  return compare(o) == 0;
-}
-
-bool LocaleValue::operator!=(const LocaleValue& o) const {
-  return compare(o) != 0;
-}
-
-bool LocaleValue::operator>=(const LocaleValue& o) const {
-  return compare(o) >= 0;
-}
-
-bool LocaleValue::operator>(const LocaleValue& o) const {
-  return compare(o) > 0;
-}
-
-}  // namespace aapt
-
-#endif  // AAPT_LOCALE_VALUE_H
diff --git a/tools/aapt2/Locale_test.cpp b/tools/aapt2/Locale_test.cpp
deleted file mode 100644
index 68b4cae..0000000
--- a/tools/aapt2/Locale_test.cpp
+++ /dev/null
@@ -1,96 +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 "Locale.h"
-
-#include <string>
-
-#include "gtest/gtest.h"
-
-#include "util/Util.h"
-
-namespace aapt {
-
-static ::testing::AssertionResult TestLanguage(const char* input,
-                                               const char* lang) {
-  std::vector<std::string> parts = util::SplitAndLowercase(input, '-');
-  LocaleValue lv;
-  ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts));
-  if (count < 0) {
-    return ::testing::AssertionFailure() << " failed to parse '" << input
-                                         << "'.";
-  }
-
-  if (count != 1) {
-    return ::testing::AssertionFailure()
-           << count << " parts were consumed parsing '" << input
-           << "' but expected 1.";
-  }
-
-  if (memcmp(lv.language, lang, std::min(strlen(lang), sizeof(lv.language))) !=
-      0) {
-    return ::testing::AssertionFailure()
-           << "expected " << lang << " but got "
-           << std::string(lv.language, sizeof(lv.language)) << ".";
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-static ::testing::AssertionResult TestLanguageRegion(const char* input,
-                                                     const char* lang,
-                                                     const char* region) {
-  std::vector<std::string> parts = util::SplitAndLowercase(input, '-');
-  LocaleValue lv;
-  ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts));
-  if (count < 0) {
-    return ::testing::AssertionFailure() << " failed to parse '" << input
-                                         << "'.";
-  }
-
-  if (count != 2) {
-    return ::testing::AssertionFailure()
-           << count << " parts were consumed parsing '" << input
-           << "' but expected 2.";
-  }
-
-  if (memcmp(lv.language, lang, std::min(strlen(lang), sizeof(lv.language))) !=
-      0) {
-    return ::testing::AssertionFailure()
-           << "expected " << input << " but got "
-           << std::string(lv.language, sizeof(lv.language)) << ".";
-  }
-
-  if (memcmp(lv.region, region, std::min(strlen(region), sizeof(lv.region))) !=
-      0) {
-    return ::testing::AssertionFailure()
-           << "expected " << region << " but got "
-           << std::string(lv.region, sizeof(lv.region)) << ".";
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-TEST(ConfigDescriptionTest, ParseLanguage) {
-  EXPECT_TRUE(TestLanguage("en", "en"));
-  EXPECT_TRUE(TestLanguage("fr", "fr"));
-  EXPECT_FALSE(TestLanguage("land", ""));
-  EXPECT_TRUE(TestLanguage("fr-land", "fr"));
-
-  EXPECT_TRUE(TestLanguageRegion("fr-rCA", "fr", "CA"));
-}
-
-}  // 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 86b1f4c..954f1ed 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -170,8 +170,8 @@
       }
 
       pb::XmlNode pb_node;
-      io::ZeroCopyInputAdaptor adaptor(in.get());
-      if (!pb_node.ParseFromZeroCopyStream(&adaptor)) {
+      io::ProtoInputStreamReader proto_reader(in.get());
+      if (!proto_reader.ReadMessage(&pb_node)) {
         context_->GetDiagnostics()->Error(DiagMessage(source_)
                                           << "failed to parse 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/development.md b/tools/aapt2/development.md
new file mode 100644
index 0000000..8ee873a
--- /dev/null
+++ b/tools/aapt2/development.md
@@ -0,0 +1,11 @@
+# AAPT2 development
+
+## Building
+All build targets can be found in `Android.bp` file. The main ones are `make -j aapt2` and `make -j aapt2_tests`
+
+`make -j aapt2` will create an aapt2 executable in `out/host/linux-x86/bin/aapt2` (on Linux). This `aapt2` executable will then be used for all the apps in the platform.
+
+Static version of the tool (without shared libraries) can be built with `make -j static_sdk_tools dist DIST_DIR=$OUTPUT_DIRECTORY BUILD_HOST_static=1`. Note, in addition to aapt2 this command will also output other statically built tools to the `$OUTPUT_DIRECTORY`.
+
+## Running tests
+Build `make -j aapt2_tests` and then (on Linux) execute `out/host/linux-x86/nativetest64/aapt2_tests/aapt2_tests`
\ No newline at end of file
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/FileStream_test.cpp b/tools/aapt2/io/FileStream_test.cpp
index c0eaa8e..7872738 100644
--- a/tools/aapt2/io/FileStream_test.cpp
+++ b/tools/aapt2/io/FileStream_test.cpp
@@ -41,46 +41,46 @@
   ASSERT_FALSE(in.HadError());
   EXPECT_THAT(in.ByteCount(), Eq(0u));
 
-  const char* buffer;
+  const void* buffer;
   size_t size;
-  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)) << in.GetError();
+  ASSERT_TRUE(in.Next(&buffer, &size)) << in.GetError();
   ASSERT_THAT(size, Eq(10u));
   ASSERT_THAT(buffer, NotNull());
   EXPECT_THAT(in.ByteCount(), Eq(10u));
-  EXPECT_THAT(StringPiece(buffer, size), Eq("this is a "));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("this is a "));
 
-  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+  ASSERT_TRUE(in.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(10u));
   ASSERT_THAT(buffer, NotNull());
   EXPECT_THAT(in.ByteCount(), Eq(20u));
-  EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
 
   in.BackUp(5u);
   EXPECT_THAT(in.ByteCount(), Eq(15u));
 
-  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+  ASSERT_TRUE(in.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(5u));
   ASSERT_THAT(buffer, NotNull());
   ASSERT_THAT(in.ByteCount(), Eq(20u));
-  EXPECT_THAT(StringPiece(buffer, size), Eq("strin"));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("strin"));
 
   // Backup 1 more than possible. Should clamp.
   in.BackUp(11u);
   EXPECT_THAT(in.ByteCount(), Eq(10u));
 
-  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+  ASSERT_TRUE(in.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(10u));
   ASSERT_THAT(buffer, NotNull());
   ASSERT_THAT(in.ByteCount(), Eq(20u));
-  EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
 
-  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+  ASSERT_TRUE(in.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(1u));
   ASSERT_THAT(buffer, NotNull());
   ASSERT_THAT(in.ByteCount(), Eq(21u));
-  EXPECT_THAT(StringPiece(buffer, size), Eq("g"));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g"));
 
-  EXPECT_FALSE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+  EXPECT_FALSE(in.Next(&buffer, &size));
   EXPECT_FALSE(in.HadError());
 }
 
@@ -93,25 +93,25 @@
   ASSERT_FALSE(out.HadError());
   EXPECT_THAT(out.ByteCount(), Eq(0u));
 
-  char* buffer;
+  void* buffer;
   size_t size;
-  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
+  ASSERT_TRUE(out.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(10u));
   ASSERT_THAT(buffer, NotNull());
   EXPECT_THAT(out.ByteCount(), Eq(10u));
-  memcpy(buffer, input.c_str(), size);
+  memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size);
 
-  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
+  ASSERT_TRUE(out.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(10u));
   ASSERT_THAT(buffer, NotNull());
   EXPECT_THAT(out.ByteCount(), Eq(20u));
-  memcpy(buffer, input.c_str() + 10u, size);
+  memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size);
 
-  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
+  ASSERT_TRUE(out.Next(&buffer, &size));
   ASSERT_THAT(size, Eq(10u));
   ASSERT_THAT(buffer, NotNull());
   EXPECT_THAT(out.ByteCount(), Eq(30u));
-  buffer[0] = input[20u];
+  reinterpret_cast<char*>(buffer)[0] = input[20u];
   out.BackUp(size - 1);
   EXPECT_THAT(out.ByteCount(), Eq(21u));
 
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/Util.h b/tools/aapt2/io/Util.h
index b07fb53..5f978a8 100644
--- a/tools/aapt2/io/Util.h
+++ b/tools/aapt2/io/Util.h
@@ -20,6 +20,7 @@
 #include <string>
 
 #include "google/protobuf/message_lite.h"
+#include "google/protobuf/io/coded_stream.h"
 
 #include "format/Archive.h"
 #include "io/File.h"
@@ -122,6 +123,23 @@
   io::InputStream* in_;
 };
 
+class ProtoInputStreamReader {
+ public:
+  explicit ProtoInputStreamReader(io::InputStream* in) : in_(in) { }
+
+  /** Deserializes a MessageLite proto from the current position in the input stream.*/
+  template <typename T> bool ReadMessage(T *message_lite) {
+    ZeroCopyInputAdaptor adapter(in_);
+    google::protobuf::io::CodedInputStream coded_stream(&adapter);
+    coded_stream.SetTotalBytesLimit(std::numeric_limits<int32_t>::max(),
+                                    coded_stream.BytesUntilTotalBytesLimit());
+    return message_lite->ParseFromCodedStream(&coded_stream);
+  }
+
+ private:
+  io::InputStream* in_;
+};
+
 }  // namespace io
 }  // namespace aapt
 
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 8e6d713..427dc92 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -33,6 +33,11 @@
     : zip_handle_(handle), zip_entry_(entry), source_(source) {}
 
 std::unique_ptr<IData> ZipFile::OpenAsData() {
+  // The file will fail to be mmaped if it is empty
+  if (zip_entry_.uncompressed_length == 0) {
+    return util::make_unique<EmptyData>();
+  }
+
   if (zip_entry_.method == kCompressStored) {
     int fd = GetFileDescriptor(zip_handle_);
 
@@ -154,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/ManifestClassGenerator.cpp b/tools/aapt2/java/ManifestClassGenerator.cpp
index be67c9c..10e504e 100644
--- a/tools/aapt2/java/ManifestClassGenerator.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator.cpp
@@ -26,21 +26,20 @@
 #include "util/Maybe.h"
 #include "xml/XmlDom.h"
 
-using ::android::StringPiece;
 using ::aapt::text::IsJavaIdentifier;
 
 namespace aapt {
 
-static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source,
+static Maybe<std::string> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source,
                                                 const std::string& value) {
-  StringPiece result = value;
+  std::string result = value;
   size_t pos = value.rfind('.');
   if (pos != std::string::npos) {
     result = result.substr(pos + 1);
   }
 
   // Normalize only the java identifier, leave the original value unchanged.
-  if (result.contains("-")) {
+  if (result.find("-") != std::string::npos) {
     result = JavaClassGenerator::TransformToFieldName(result);
   }
 
@@ -64,7 +63,7 @@
     return false;
   }
 
-  Maybe<StringPiece> result =
+  Maybe<std::string> result =
       ExtractJavaIdentifier(diag, source.WithLine(el->line_number), attr->value);
   if (!result) {
     return false;
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/BigBuffer.h b/tools/aapt2/util/BigBuffer.h
index 3045255..d4b3abc 100644
--- a/tools/aapt2/util/BigBuffer.h
+++ b/tools/aapt2/util/BigBuffer.h
@@ -68,7 +68,7 @@
    */
   explicit BigBuffer(size_t block_size);
 
-  BigBuffer(BigBuffer&& rhs);
+  BigBuffer(BigBuffer&& rhs) noexcept;
 
   /**
    * Number of occupied bytes in all the allocated blocks.
@@ -136,7 +136,7 @@
 inline BigBuffer::BigBuffer(size_t block_size)
     : block_size_(block_size), size_(0) {}
 
-inline BigBuffer::BigBuffer(BigBuffer&& rhs)
+inline BigBuffer::BigBuffer(BigBuffer&& rhs) noexcept
     : block_size_(rhs.block_size_),
       size_(rhs.size_),
       blocks_(std::move(rhs.blocks_)) {}
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/aapt2/util/ImmutableMap.h b/tools/aapt2/util/ImmutableMap.h
index 59858e4..1727b18 100644
--- a/tools/aapt2/util/ImmutableMap.h
+++ b/tools/aapt2/util/ImmutableMap.h
@@ -32,8 +32,8 @@
   using const_iterator =
       typename std::vector<std::pair<TKey, TValue>>::const_iterator;
 
-  ImmutableMap(ImmutableMap&&) = default;
-  ImmutableMap& operator=(ImmutableMap&&) = default;
+  ImmutableMap(ImmutableMap&&) noexcept = default;
+  ImmutableMap& operator=(ImmutableMap&&) noexcept = default;
 
   static ImmutableMap<TKey, TValue> CreatePreSorted(
       std::initializer_list<std::pair<TKey, TValue>> list) {
diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h
index 9a82418..031276c 100644
--- a/tools/aapt2/util/Maybe.h
+++ b/tools/aapt2/util/Maybe.h
@@ -46,7 +46,7 @@
   template <typename U>
   Maybe(const Maybe<U>& rhs);  // NOLINT(implicit)
 
-  Maybe(Maybe&& rhs);
+  Maybe(Maybe&& rhs) noexcept;
 
   template <typename U>
   Maybe(Maybe<U>&& rhs);  // NOLINT(implicit)
@@ -56,7 +56,7 @@
   template <typename U>
   Maybe& operator=(const Maybe<U>& rhs);
 
-  Maybe& operator=(Maybe&& rhs);
+  Maybe& operator=(Maybe&& rhs) noexcept;
 
   template <typename U>
   Maybe& operator=(Maybe<U>&& rhs);
@@ -134,7 +134,7 @@
 }
 
 template <typename T>
-Maybe<T>::Maybe(Maybe&& rhs) : nothing_(rhs.nothing_) {
+Maybe<T>::Maybe(Maybe&& rhs) noexcept : nothing_(rhs.nothing_) {
   if (!rhs.nothing_) {
     rhs.nothing_ = true;
 
@@ -192,7 +192,7 @@
 }
 
 template <typename T>
-inline Maybe<T>& Maybe<T>::operator=(Maybe&& rhs) {
+inline Maybe<T>& Maybe<T>::operator=(Maybe&& rhs) noexcept {
   // Delegate to the actual assignment.
   return move(std::forward<Maybe<T>>(rhs));
 }
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 934847f..91cd1cb 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -492,6 +492,7 @@
 def verify_protected(clazz):
     """Verify that no protected methods or fields are allowed."""
     for m in clazz.methods:
+        if m.name == "finalize": continue
         if "protected" in m.split:
             error(clazz, m, "M7", "Protected methods not allowed; must be public")
     for f in clazz.fields:
@@ -1025,6 +1026,10 @@
     # Resources defined by files are foo_bar_baz
     if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]:
         for f in clazz.fields:
+            if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
+            if f.name.startswith("config_"):
+                error(clazz, f, None, "Expected config name to be config_fooBarBaz style")
+
             if re.match("[a-z1-9_]+$", f.name): continue
             error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style")
 
@@ -1361,6 +1366,60 @@
             error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()")
 
 
+def verify_pfd(clazz):
+    """Verify that android APIs use PFD over FD."""
+    examine = clazz.ctors + clazz.methods
+    for m in examine:
+        if m.typ == "java.io.FileDescriptor":
+            error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
+        if m.typ == "int":
+            if "Fd" in m.name or "FD" in m.name or "FileDescriptor" in m.name:
+                error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
+        for arg in m.args:
+            if arg == "java.io.FileDescriptor":
+                error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
+
+    for f in clazz.fields:
+        if f.typ == "java.io.FileDescriptor":
+            error(clazz, f, "FW11", "Must use ParcelFileDescriptor")
+
+
+def verify_numbers(clazz):
+    """Discourage small numbers types like short and byte."""
+
+    discouraged = ["short","byte"]
+
+    for c in clazz.ctors:
+        for arg in c.args:
+            if arg in discouraged:
+                warn(clazz, c, "FW12", "Should avoid odd sized primitives; use int instead")
+
+    for f in clazz.fields:
+        if f.typ in discouraged:
+            warn(clazz, f, "FW12", "Should avoid odd sized primitives; use int instead")
+
+    for m in clazz.methods:
+        if m.typ in discouraged:
+            warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
+        for arg in m.args:
+            if arg in discouraged:
+                warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
+
+
+def verify_singleton(clazz):
+    """Catch singleton objects with constructors."""
+
+    singleton = False
+    for m in clazz.methods:
+        if m.name.startswith("get") and m.name.endswith("Instance") and " static " in m.raw:
+            singleton = True
+
+    if singleton:
+        for c in clazz.ctors:
+            error(clazz, c, None, "Singleton classes should use getInstance() methods")
+
+
+
 def is_interesting(clazz):
     """Test if given class is interesting from an Android PoV."""
 
@@ -1431,6 +1490,9 @@
     verify_tense(clazz)
     verify_icu(clazz)
     verify_clone(clazz)
+    verify_pfd(clazz)
+    verify_numbers(clazz)
+    verify_singleton(clazz)
 
 
 def examine_stream(stream):
diff --git a/tools/fonts/add_additional_fonts.py b/tools/fonts/add_additional_fonts.py
deleted file mode 100644
index bf4af2b..0000000
--- a/tools/fonts/add_additional_fonts.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import sys
-
-def main(argv):
-    original_file = 'frameworks/base/data/fonts/fonts.xml'
-
-    if len(argv) == 3:
-        output_file_path = argv[1]
-        override_file_path = argv[2]
-    else:
-        raise ValueError("Wrong number of arguments %s" % len(argv))
-
-    fallbackPlaceholderFound = False
-    with open(original_file, 'r') as input_file:
-        with open(output_file_path, 'w') as output_file:
-            for line in input_file:
-                # If we've found the spot to add additional fonts, add them.
-                if line.strip() == '<!-- fallback fonts -->':
-                    fallbackPlaceholderFound = True
-                    with open(override_file_path) as override_file:
-                        for override_line in override_file:
-                            output_file.write(override_line)
-                output_file.write(line)
-    if not fallbackPlaceholderFound:
-        raise ValueError('<!-- fallback fonts --> not found in source file: %s' % original_file)
-
-if __name__ == '__main__':
-    main(sys.argv)
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 6c46e67..fdc800b 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -212,8 +212,8 @@
     move_from_files(args.input_greylists, uncategorized, light_greylist)
     move_from_files(args.input_blacklists, uncategorized, blacklist)
 
-    # Iterate over all uncategorized members and move serialization API to light greylist.
-    move_serialization(uncategorized, light_greylist)
+    # Iterate over all uncategorized members and move serialization API to whitelist.
+    move_serialization(uncategorized, whitelist)
 
     # Extract package names of members from whitelist and light greylist, which
     # are assumed to have been finalized at this point. Assign all uncategorized
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
index 8f79318..4716241 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py
@@ -85,5 +85,23 @@
         self.assertEqual(
             dst, set([ "Lfoo/bar/ClassA;->abc()J", "Lfoo/bar/ClassA;->def()J" ]))
 
+    def test_move_serialization(self):
+        # All the entries should be moved apart from the last one
+        src = set([ "Lfoo/bar/ClassA;->readObject(Ljava/io/ObjectInputStream;)V",
+                    "Lfoo/bar/ClassA;->readObjectNoData()V",
+                    "Lfoo/bar/ClassA;->readResolve()Ljava/lang/Object;",
+                    "Lfoo/bar/ClassA;->serialVersionUID:J",
+                    "Lfoo/bar/ClassA;->serialPersistentFields:[Ljava/io/ObjectStreamField;",
+                    "Lfoo/bar/ClassA;->writeObject(Ljava/io/ObjectOutputStream;)V",
+                    "Lfoo/bar/ClassA;->writeReplace()Ljava/lang/Object;",
+                    # Should not be moved as signature does not match
+                    "Lfoo/bar/ClassA;->readObject(Ljava/io/ObjectInputStream;)I"])
+        expectedToMove = len(src) - 1
+        dst = set()
+        packages = set([ "Lfoo/bar/" ])
+        move_serialization(src, dst)
+        self.assertEqual(len(src), 1)
+        self.assertEqual(len(dst), expectedToMove)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 639f980..0cf1046 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -138,7 +138,7 @@
     size_t base = 0;
     size_t found;
     while (true) {
-        found = args.find_first_of(" ", base);
+        found = args.find_first_of(' ', base);
         if (found != base) {
             string arg = args.substr(base, found - base);
             printf(" \"%s\",", arg.c_str());
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 9915479..56c8428 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -234,9 +234,11 @@
                     }
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", const std::map<int, int64_t>& arg%d_1, "
-                             "const std::map<int, char const*>& arg%d_2, "
-                             "const std::map<int, float>& arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+                             "const std::map<int, int64_t>& arg%d_2, "
+                             "const std::map<int, char const*>& arg%d_3, "
+                             "const std::map<int, float>& arg%d_4",
+                             argIndex, argIndex, argIndex, argIndex);
             } else {
                 fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             }
@@ -302,6 +304,13 @@
                     fprintf(out, "         event.end();\n");
                     fprintf(out, "    }\n");
 
+                    fprintf(out, "    for (const auto& it : arg%d_4) {\n", argIndex);
+                    fprintf(out, "         event.begin();\n");
+                    fprintf(out, "         event << it.first;\n");
+                    fprintf(out, "         event << it.second;\n");
+                    fprintf(out, "         event.end();\n");
+                    fprintf(out, "    }\n");
+
                     fprintf(out, "    event.end();\n\n");
             } else {
                 if (*arg == JAVA_TYPE_STRING) {
@@ -344,9 +353,11 @@
                    }
                }
            } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", const std::map<int, int64_t>& arg%d_1, "
-                             "const std::map<int, char const*>& arg%d_2, "
-                             "const std::map<int, float>& arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+                             "const std::map<int, int64_t>& arg%d_2, "
+                             "const std::map<int, char const*>& arg%d_3, "
+                             "const std::map<int, float>& arg%d_4",
+                             argIndex, argIndex, argIndex, argIndex);
            } else {
                fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
            }
@@ -374,7 +385,8 @@
                    }
                }
            } else  if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", arg%d_1, arg%d_2, arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4",
+                        argIndex, argIndex, argIndex, argIndex);
            } else {
                fprintf(out, ", arg%d", argIndex);
            }
@@ -529,10 +541,14 @@
                 }
             }
         } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
-            fprintf(out, ", const std::map<int, int64_t>& %s_int"
+            fprintf(out, ", const std::map<int, int32_t>& %s_int"
+                         ", const std::map<int, int64_t>& %s_long"
                          ", const std::map<int, char const*>& %s_str"
                          ", const std::map<int, float>& %s_float",
-                         field->name.c_str(), field->name.c_str(), field->name.c_str());
+                         field->name.c_str(),
+                         field->name.c_str(),
+                         field->name.c_str(),
+                         field->name.c_str());
         } else {
             fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str());
         }
@@ -561,9 +577,11 @@
                     }
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", const std::map<int, int64_t>& arg%d_1, "
-                             "const std::map<int, char const*>& arg%d_2, "
-                             "const std::map<int, float>& arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+                             "const std::map<int, int64_t>& arg%d_2, "
+                             "const std::map<int, char const*>& arg%d_3, "
+                             "const std::map<int, float>& arg%d_4",
+                             argIndex, argIndex, argIndex, argIndex);
             } else {
                 fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             }
@@ -976,6 +994,7 @@
 }
 
 static void write_key_value_map_jni(FILE* out) {
+   fprintf(out, "    std::map<int, int32_t> int32_t_map;\n");
    fprintf(out, "    std::map<int, int64_t> int64_t_map;\n");
    fprintf(out, "    std::map<int, float> float_map;\n");
    fprintf(out, "    std::map<int, char const*> string_map;\n\n");
@@ -989,9 +1008,11 @@
 
    fprintf(out, "    std::vector<std::unique_ptr<ScopedUtfChars>> scoped_ufs;\n\n");
 
+   fprintf(out, "    jclass jint_class = env->FindClass(\"java/lang/Integer\");\n");
    fprintf(out, "    jclass jlong_class = env->FindClass(\"java/lang/Long\");\n");
    fprintf(out, "    jclass jfloat_class = env->FindClass(\"java/lang/Float\");\n");
    fprintf(out, "    jclass jstring_class = env->FindClass(\"java/lang/String\");\n");
+   fprintf(out, "    jmethodID jget_int_method = env->GetMethodID(jint_class, \"intValue\", \"()I\");\n");
    fprintf(out, "    jmethodID jget_long_method = env->GetMethodID(jlong_class, \"longValue\", \"()J\");\n");
    fprintf(out, "    jmethodID jget_float_method = env->GetMethodID(jfloat_class, \"floatValue\", \"()F\");\n\n");
 
@@ -1000,7 +1021,9 @@
    fprintf(out, "        jint key = env->CallIntMethod(value_map, jget_key_method, i);\n");
    fprintf(out, "        jobject jvalue_obj = env->CallObjectMethod(value_map, jget_value_method, i);\n");
    fprintf(out, "        if (jvalue_obj == NULL) { continue; }\n");
-   fprintf(out, "        if (env->IsInstanceOf(jvalue_obj, jlong_class)) {\n");
+   fprintf(out, "        if (env->IsInstanceOf(jvalue_obj, jint_class)) {\n");
+   fprintf(out, "            int32_t_map[key] = env->CallIntMethod(jvalue_obj, jget_int_method);\n");
+   fprintf(out, "        } else if (env->IsInstanceOf(jvalue_obj, jlong_class)) {\n");
    fprintf(out, "            int64_t_map[key] = env->CallLongMethod(jvalue_obj, jget_long_method);\n");
    fprintf(out, "        } else if (env->IsInstanceOf(jvalue_obj, jfloat_class)) {\n");
    fprintf(out, "            float_map[key] = env->CallFloatMethod(jvalue_obj, jget_float_method);\n");
@@ -1129,7 +1152,7 @@
                     }
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", int64_t_map, string_map, float_map");
+                fprintf(out, ", int32_t_map, int64_t_map, string_map, float_map");
             } else {
                 const char *argName = (*arg == JAVA_TYPE_STRING) ? "str" : "arg";
                 fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index ce8d71d..7472278 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -332,9 +332,10 @@
     public String preSharedKey;
 
     /**
-     * Up to four WEP keys. Either an ASCII string enclosed in double
-     * quotation marks (e.g., {@code "abcdef"}) or a string
-     * of hex digits (e.g., {@code 0102030405}).
+     * Four WEP keys. For each of the four values, provide either an ASCII
+     * string enclosed in double quotation marks (e.g., {@code "abcdef"}),
+     * a string of hex digits (e.g., {@code 0102030405}), or an empty string
+     * (e.g., {@code ""}).
      * <p/>
      * When the value of one of these keys is read, the actual key is
      * not returned, just a "*" if the key has a value, or the null
@@ -512,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;
@@ -520,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 7a91347..59ba8e7 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1698,9 +1698,7 @@
      * @return the list of access points found in the most recent scan. An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get valid results.  If there is a remote exception (e.g., either a communication
-     * problem with the system service or an exception within the framework) an empty list will be
-     * returned.
+     * in order to get valid results.
      */
     public List<ScanResult> getScanResults() {
         try {